Skip to content

Commit e53c704

Browse files
odeimaizpcrespov
andauthored
✨ Front-end: Drafts "Pending Users" view on the PO center (#7745)
Co-authored-by: Pedro Crespo-Valero <[email protected]>
1 parent 7f8693e commit e53c704

File tree

2 files changed

+106
-66
lines changed

2 files changed

+106
-66
lines changed

services/static-webserver/client/source/class/osparc/data/Resources.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1065,6 +1065,10 @@ qx.Class.define("osparc.data.Resources", {
10651065
method: "GET",
10661066
url: statics.API + "/admin/user-accounts?review_status=PENDING"
10671067
},
1068+
getReviewedUsers: {
1069+
method: "GET",
1070+
url: statics.API + "/admin/user-accounts?review_status=REVIEWED"
1071+
},
10681072
approveUser: {
10691073
method: "POST",
10701074
url: statics.API + "/admin/user-accounts:approve"

services/static-webserver/client/source/class/osparc/po/UsersPending.js

Lines changed: 102 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -20,65 +20,82 @@ qx.Class.define("osparc.po.UsersPending", {
2020
extend: osparc.po.BaseView,
2121

2222
statics: {
23-
getPendingUsers: function() {
24-
return new Promise(resolve => {
25-
resolve({
26-
data: [{
27-
name: "John Doe",
28-
29-
date: "2025-01-01 00:00:00.702394",
30-
status: "PENDING",
31-
info: {
32-
"institution": "ETH Zurich",
33-
"department": "Department of Physics",
34-
"position": "PhD Student",
35-
"country": "Switzerland",
36-
"city": "Zurich",
37-
},
38-
}, {
39-
name: "Jane Doe",
40-
41-
date: "2025-01-01 00:01:00.702394",
42-
status: "REJECTED",
43-
info: {
44-
"institution": "ETH Zurich",
45-
"department": "Department of Physics",
46-
"position": "PhD Student",
47-
"country": "Switzerland",
48-
"city": "Zurich",
49-
},
50-
}, {
51-
name: "Alice Smith",
52-
53-
date: "2025-01-01 00:02:00.702394",
54-
status: "APPROVED",
55-
info: {
56-
"institution": "ETH Zurich",
57-
"department": "Department of Physics",
58-
"position": "PhD Student",
59-
"country": "Switzerland",
60-
"city": "Zurich",
61-
},
62-
}]
63-
});
23+
createInvitationForm: function() {
24+
const form = new qx.ui.form.Form();
25+
26+
const extraCreditsInUsd = new qx.ui.form.Spinner().set({
27+
minimum: 0,
28+
maximum: 1000,
29+
value: 100
6430
});
31+
form.add(extraCreditsInUsd, qx.locale.Manager.tr("Welcome Credits (USD)"), null, "credits");
32+
33+
const withExpiration = new qx.ui.form.CheckBox().set({
34+
value: false
35+
});
36+
form.add(withExpiration, qx.locale.Manager.tr("With expiration"), null, "withExpiration");
37+
38+
const trialDays = new qx.ui.form.Spinner().set({
39+
minimum: 1,
40+
maximum: 1000,
41+
value: 1
42+
});
43+
withExpiration.bind("value", trialDays, "visibility", {
44+
converter: val => val ? "visible" : "excluded"
45+
});
46+
form.add(trialDays, qx.locale.Manager.tr("Trial Days"), null, "trialDays");
47+
48+
return form;
6549
},
6650

6751
createApproveButton: function(email) {
68-
const button = new osparc.ui.form.FetchButton(qx.locale.Manager.tr("Approve"));
52+
const button = new qx.ui.form.Button(qx.locale.Manager.tr("Approve"));
6953
button.addListener("execute", () => {
70-
button.setFetching(true);
71-
const params = {
72-
data: {
73-
email,
74-
},
75-
};
76-
osparc.data.Resources.fetch("poUsers", "approveUser", params)
77-
.then(() => {
78-
osparc.FlashMessenger.logAs(qx.locale.Manager.tr("User approved"), "INFO");
79-
})
80-
.catch(err => osparc.FlashMessenger.logError(err))
81-
.finally(() => button.setFetching(false));
54+
const form = this.createInvitationForm();
55+
const approveBtn = new osparc.ui.form.FetchButton(qx.locale.Manager.tr("Approve"));
56+
approveBtn.set({
57+
appearance: "form-button"
58+
});
59+
form.addButton(approveBtn);
60+
const layout = new qx.ui.container.Composite(new qx.ui.layout.VBox(10));
61+
const invitationForm = new qx.ui.form.renderer.Single(form);
62+
layout.add(invitationForm);
63+
const win = osparc.ui.window.Window.popUpInWindow(layout, email, 350, 150).set({
64+
clickAwayClose: false,
65+
resizable: false,
66+
showClose: true
67+
});
68+
win.open();
69+
approveBtn.addListener("execute", () => {
70+
if (!osparc.data.Permissions.getInstance().canDo("user.invitation.generate", true)) {
71+
return;
72+
}
73+
if (form.validate()) {
74+
approveBtn.setFetching(true);
75+
const params = {
76+
data: {
77+
email,
78+
},
79+
};
80+
params.data["invitation"] = {};
81+
const extraCreditsInUsd = form.getItems()["credits"].getValue();
82+
if (extraCreditsInUsd > 0) {
83+
params.data["invitation"]["extraCreditsInUsd"] = extraCreditsInUsd;
84+
}
85+
if (form.getItems()["withExpiration"].getValue()) {
86+
params.data["invitation"]["trialAccountDays"] = form.getItems()["trialDays"].getValue();
87+
}
88+
osparc.data.Resources.fetch("poUsers", "approveUser", params)
89+
.then(() => {
90+
osparc.FlashMessenger.logAs(qx.locale.Manager.tr("User approved"), "INFO");
91+
})
92+
.catch(err => osparc.FlashMessenger.logError(err))
93+
.finally(() => {
94+
approveBtn.setFetching(false);
95+
win.close();
96+
});
97+
}
98+
});
8299
});
83100
return button;
84101
},
@@ -136,6 +153,16 @@ qx.Class.define("osparc.po.UsersPending", {
136153
_createChildControlImpl: function(id) {
137154
let control;
138155
switch (id) {
156+
case "reload-button":
157+
control = new qx.ui.form.Button(this.tr("Reload")).set({
158+
allowGrowX: false,
159+
});
160+
control.addListener("execute", () => {
161+
this.getChildControl("pending-users-layout").removeAll();
162+
this.__populatePendingUsersLayout();
163+
});
164+
this._add(control);
165+
break;
139166
case "pending-users-container":
140167
control = new qx.ui.container.Scroll();
141168
this._add(control, {
@@ -153,6 +180,7 @@ qx.Class.define("osparc.po.UsersPending", {
153180
},
154181

155182
_buildLayout: function() {
183+
this.getChildControl("reload-button");
156184
this.getChildControl("pending-users-container");
157185

158186
this.__populatePendingUsersLayout();
@@ -182,14 +210,14 @@ qx.Class.define("osparc.po.UsersPending", {
182210
column: 2,
183211
});
184212

185-
pendingUsersLayout.add(new qx.ui.basic.Label(this.tr("Info")).set({
213+
pendingUsersLayout.add(new qx.ui.basic.Label(this.tr("Status")).set({
186214
font: "text-14"
187215
}), {
188216
row: 0,
189217
column: 3,
190218
});
191219

192-
pendingUsersLayout.add(new qx.ui.basic.Label(this.tr("Status")).set({
220+
pendingUsersLayout.add(new qx.ui.basic.Label(this.tr("Info")).set({
193221
font: "text-14"
194222
}), {
195223
row: 0,
@@ -209,24 +237,24 @@ qx.Class.define("osparc.po.UsersPending", {
209237

210238
let row = 1;
211239
pendingUsers.forEach(pendingUser => {
212-
pendingUsersLayout.add(new qx.ui.basic.Label(pendingUser.name), {
240+
pendingUsersLayout.add(new qx.ui.basic.Label(pendingUser.firstName + " " + pendingUser.lastName), {
213241
row,
214242
column: 0,
215243
});
216244
pendingUsersLayout.add(new qx.ui.basic.Label(pendingUser.email), {
217245
row,
218246
column: 1,
219247
});
220-
pendingUsersLayout.add(new qx.ui.basic.Label(osparc.utils.Utils.formatDateAndTime(new Date(pendingUser.date))), {
248+
pendingUsersLayout.add(new qx.ui.basic.Label(pendingUser.date ? osparc.utils.Utils.formatDateAndTime(new Date(pendingUser.date)) : "-"), {
221249
row,
222250
column: 2,
223251
});
224-
const infoButton = this.self().createInfoButton(pendingUser.info);
225-
pendingUsersLayout.add(infoButton, {
252+
pendingUsersLayout.add(new qx.ui.basic.Label(pendingUser.accountRequestStatus.toLowerCase()), {
226253
row,
227254
column: 3,
228255
});
229-
pendingUsersLayout.add(new qx.ui.basic.Label(pendingUser.status.toLowerCase()), {
256+
const infoButton = this.self().createInfoButton(pendingUser);
257+
pendingUsersLayout.add(infoButton, {
230258
row,
231259
column: 4,
232260
});
@@ -236,7 +264,7 @@ qx.Class.define("osparc.po.UsersPending", {
236264
column: 5,
237265
});
238266

239-
switch (pendingUser.status) {
267+
switch (pendingUser.accountRequestStatus) {
240268
case "PENDING": {
241269
const approveButton = this.self().createApproveButton(pendingUser.email);
242270
buttonsLayout.add(approveButton);
@@ -250,8 +278,12 @@ qx.Class.define("osparc.po.UsersPending", {
250278
break;
251279
}
252280
case "APPROVED": {
281+
/*
253282
const resendEmailButton = this.self().createResendEmailButton(pendingUser.email);
254283
buttonsLayout.add(resendEmailButton);
284+
*/
285+
const rejectButton = this.self().createRejectButton(pendingUser.email);
286+
buttonsLayout.add(rejectButton);
255287
break;
256288
}
257289
}
@@ -260,13 +292,17 @@ qx.Class.define("osparc.po.UsersPending", {
260292
},
261293

262294
__populatePendingUsersLayout: function() {
263-
// osparc.data.Resources.fetch("poUsers", "getPendingUsers", params)
264-
this.self().getPendingUsers()
265-
.then(pendingUsers => {
295+
Promise.all([
296+
osparc.data.Resources.fetch("poUsers", "getPendingUsers"),
297+
osparc.data.Resources.fetch("poUsers", "getReviewedUsers")
298+
])
299+
.then(resps => {
300+
const pendingUsers = resps[0];
301+
const reviewedUsers = resps[1];
266302
const pendingUsersLayout = this.getChildControl("pending-users-layout");
267303
pendingUsersLayout.removeAll();
268304
this.__addHeader();
269-
this.__addRows(pendingUsers["data"]);
305+
this.__addRows(pendingUsers.concat(reviewedUsers));
270306
})
271307
.catch(err => osparc.FlashMessenger.logError(err));
272308
}

0 commit comments

Comments
 (0)