Skip to content

Commit 8af9e3e

Browse files
authored
✨ Admin Center: Manage Pricing Plans and read Maintenance (ITISFoundation#5554)
1 parent 5e33f7f commit 8af9e3e

26 files changed

+1947
-99
lines changed

services/static-webserver/client/source/class/osparc/Application.js

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -222,16 +222,17 @@ qx.Class.define("osparc.Application", {
222222
},
223223

224224
__startupChecks: function() {
225+
// first, pop up new release window
226+
this.__checkNewRelease();
227+
225228
const platformName = osparc.store.StaticInfo.getInstance().getPlatformName();
226229
if (platformName !== "master") {
227-
// first, pop up new release window
228-
this.__checkNewRelease();
229230
// then, pop up cookies accepted window. It will go on top.
230231
this.__checkCookiesAccepted();
231232
}
232233
},
233234

234-
__checkNewRelease: async function() {
235+
__checkNewRelease: function() {
235236
if (osparc.NewRelease.firstTimeISeeThisFrontend()) {
236237
const newRelease = new osparc.NewRelease();
237238
const title = this.tr("New Release");
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
/* ************************************************************************
2+
3+
osparc - the simcore frontend
4+
5+
https://osparc.io
6+
7+
Copyright:
8+
2024 IT'IS Foundation, https://itis.swiss
9+
10+
License:
11+
MIT: https://opensource.org/licenses/MIT
12+
13+
Authors:
14+
* Odei Maiz (odeimaiz)
15+
16+
************************************************************************ */
17+
18+
qx.Class.define("osparc.admin.AdminCenter", {
19+
extend: qx.ui.core.Widget,
20+
21+
construct: function() {
22+
this.base(arguments);
23+
24+
this._setLayout(new qx.ui.layout.VBox());
25+
26+
this.set({
27+
padding: 10
28+
});
29+
30+
const tabViews = new qx.ui.tabview.TabView().set({
31+
barPosition: "left",
32+
contentPadding: 0
33+
});
34+
const miniProfile = osparc.desktop.credits.MyAccount.createMiniProfileView().set({
35+
paddingRight: 10
36+
});
37+
tabViews.getChildControl("bar").add(miniProfile);
38+
39+
const pricingPlans = this.__getPricingPlansPage();
40+
tabViews.add(pricingPlans);
41+
42+
const maintenance = this.__getMaintenancePage();
43+
tabViews.add(maintenance);
44+
45+
this._add(tabViews, {
46+
flex: 1
47+
});
48+
},
49+
50+
members: {
51+
__widgetToPage: function(title, iconSrc, widget) {
52+
const page = new osparc.desktop.preferences.pages.BasePage(title, iconSrc);
53+
widget.set({
54+
margin: 10
55+
});
56+
page.add(widget, {
57+
flex: 1
58+
});
59+
return page;
60+
},
61+
62+
__getPricingPlansPage: function() {
63+
const title = this.tr("Pricing Plans");
64+
const iconSrc = "@FontAwesome5Solid/dollar-sign/22";
65+
const pricingPlans = new osparc.pricing.PlanManager();
66+
const page = this.__widgetToPage(title, iconSrc, pricingPlans);
67+
return page;
68+
},
69+
70+
__getMaintenancePage: function() {
71+
const title = this.tr("Maintenance");
72+
const iconSrc = "@FontAwesome5Solid/wrench/22";
73+
const maintenance = new osparc.admin.Maintenance();
74+
const page = this.__widgetToPage(title, iconSrc, maintenance);
75+
return page;
76+
}
77+
}
78+
});
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
/* ************************************************************************
2+
3+
osparc - the simcore frontend
4+
5+
https://osparc.io
6+
7+
Copyright:
8+
2024 IT'IS Foundation, https://itis.swiss
9+
10+
License:
11+
MIT: https://opensource.org/licenses/MIT
12+
13+
Authors:
14+
* Odei Maiz (odeimaiz)
15+
16+
************************************************************************ */
17+
18+
qx.Class.define("osparc.admin.AdminCenterWindow", {
19+
extend: osparc.ui.window.SingletonWindow,
20+
21+
construct: function() {
22+
this.base(arguments, "admin-center", this.tr("Admin Center"));
23+
24+
const viewWidth = 800;
25+
const viewHeight = 600;
26+
27+
this.set({
28+
layout: new qx.ui.layout.Grow(),
29+
modal: true,
30+
width: viewWidth,
31+
height: viewHeight,
32+
showMaximize: false,
33+
showMinimize: false,
34+
resizable: true,
35+
appearance: "service-window"
36+
});
37+
38+
const adminCenter = new osparc.admin.AdminCenter();
39+
this.add(adminCenter);
40+
},
41+
42+
statics: {
43+
openWindow: function() {
44+
const accountWindow = new osparc.admin.AdminCenterWindow();
45+
accountWindow.center();
46+
accountWindow.open();
47+
return accountWindow;
48+
}
49+
}
50+
});
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
/* ************************************************************************
2+
3+
osparc - the simcore frontend
4+
5+
https://osparc.io
6+
7+
Copyright:
8+
2024 IT'IS Foundation, https://itis.swiss
9+
10+
License:
11+
MIT: https://opensource.org/licenses/MIT
12+
13+
Authors:
14+
* Odei Maiz (odeimaiz)
15+
16+
************************************************************************ */
17+
18+
qx.Class.define("osparc.admin.Maintenance", {
19+
extend: osparc.po.BaseView,
20+
21+
members: {
22+
_createChildControlImpl: function(id) {
23+
let control;
24+
switch (id) {
25+
case "maintenance-container": {
26+
control = new qx.ui.container.Composite(new qx.ui.layout.VBox(5));
27+
this._add(control, {
28+
flex: 1
29+
});
30+
break;
31+
}
32+
}
33+
return control || this.base(arguments, id);
34+
},
35+
36+
_buildLayout: function() {
37+
osparc.data.Resources.get("maintenance")
38+
.then(scheduledMaintenance => {
39+
if (scheduledMaintenance) {
40+
this.__populateMaintenanceLayout(JSON.parse(scheduledMaintenance))
41+
} else {
42+
this.__populateMaintenanceLayout(null)
43+
}
44+
})
45+
.catch(err => console.error(err));
46+
},
47+
48+
__populateMaintenanceLayout: function(data) {
49+
const vBox = this.getChildControl("maintenance-container");
50+
vBox.removeAll();
51+
52+
if (data) {
53+
const respLabel = new qx.ui.basic.Label(this.tr("Start and End dates go in UTC time zone"));
54+
vBox.add(respLabel);
55+
56+
const invitationRespViewer = new osparc.ui.basic.JsonTreeWidget(data, "maintenance-data");
57+
const container = new qx.ui.container.Scroll();
58+
container.add(invitationRespViewer);
59+
vBox.add(container, {
60+
flex: 1
61+
});
62+
} else {
63+
const label = new qx.ui.basic.Label().set({
64+
value: this.tr("No Maintenance scheduled")
65+
});
66+
vBox.add(label);
67+
}
68+
}
69+
}
70+
});

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

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -285,11 +285,15 @@ qx.Class.define("osparc.data.Permissions", {
285285
},
286286

287287
isTester: function() {
288-
return ["tester", "product_owner", "admin"].includes(this.getRole());
288+
return ["admin", "product_owner", "tester"].includes(this.getRole());
289289
},
290290

291291
isProductOwner: function() {
292-
return ["product_owner", "admin"].includes(this.getRole());
293-
}
292+
return ["admin", "product_owner"].includes(this.getRole());
293+
},
294+
295+
isAdmin: function() {
296+
return ["admin"].includes(this.getRole());
297+
},
294298
}
295299
});

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

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -449,6 +449,70 @@ qx.Class.define("osparc.data.Resources", {
449449
}
450450
}
451451
},
452+
453+
/*
454+
* PRICING PLANS
455+
*/
456+
"pricingPlans": {
457+
useCache: true,
458+
endpoints: {
459+
get: {
460+
method: "GET",
461+
url: statics.API + "/admin/pricing-plans"
462+
},
463+
getOne: {
464+
method: "GET",
465+
url: statics.API + "/admin/pricing-plans/{pricingPlanId}"
466+
},
467+
update: {
468+
method: "PUT",
469+
url: statics.API + "/admin/pricing-plans/{pricingPlanId}"
470+
},
471+
post: {
472+
method: "POST",
473+
url: statics.API + "/admin/pricing-plans"
474+
},
475+
}
476+
},
477+
478+
/*
479+
* PRICING UNITS
480+
*/
481+
"pricingUnits": {
482+
useCache: true,
483+
endpoints: {
484+
getOne: {
485+
method: "GET",
486+
url: statics.API + "/admin/pricing-plans/{pricingPlanId}/pricing-units/{pricingUnitId}"
487+
},
488+
update: {
489+
method: "PUT",
490+
url: statics.API + "/admin/pricing-plans/{pricingPlanId}/pricing-units/{pricingUnitId}"
491+
},
492+
post: {
493+
method: "POST",
494+
url: statics.API + "/admin/pricing-plans/{pricingPlanId}/pricing-units"
495+
},
496+
}
497+
},
498+
499+
/*
500+
* BILLABLE SERVICES
501+
*/
502+
"billableServices": {
503+
useCache: true,
504+
endpoints: {
505+
get: {
506+
method: "GET",
507+
url: statics.API + "/admin/pricing-plans/{pricingPlanId}/billable-services"
508+
},
509+
post: {
510+
method: "POST",
511+
url: statics.API + "/admin/pricing-plans/{pricingPlanId}/billable-services"
512+
},
513+
}
514+
},
515+
452516
/*
453517
* PORT COMPATIBILITY
454518
*/
@@ -491,6 +555,7 @@ qx.Class.define("osparc.data.Resources", {
491555
},
492556
/*
493557
* SCHEDULED MAINTENANCE
558+
* Example: {"start": "2023-01-17T14:45:00.000Z", "end": "2023-01-17T23:00:00.000Z", "reason": "Release 1.0.4"}
494559
*/
495560
"maintenance": {
496561
endpoints: {

services/static-webserver/client/source/class/osparc/desktop/organizations/OrganizationDetails.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,6 @@ qx.Class.define("osparc.desktop.organizations.OrganizationDetails", {
165165
const tabView = new qx.ui.tabview.TabView().set({
166166
contentPadding: 10
167167
});
168-
tabView.getChildControl("pane");
169168

170169
const membersListPage = this.__createTabPage(this.tr("Members"), "@FontAwesome5Solid/users/14");
171170
const membersList = this.__membersList = new osparc.desktop.organizations.MembersList();

services/static-webserver/client/source/class/osparc/navigation/UserMenu.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,11 @@ qx.Class.define("osparc.navigation.UserMenu", {
4949
control.addListener("execute", () => osparc.desktop.credits.MyAccountWindow.openWindow(), this);
5050
this.add(control);
5151
break;
52+
case "admin-center":
53+
control = new qx.ui.menu.Button(this.tr("Admin Center"));
54+
control.addListener("execute", () => osparc.admin.AdminCenterWindow.openWindow(), this);
55+
this.add(control);
56+
break;
5257
case "po-center":
5358
control = new qx.ui.menu.Button(this.tr("PO Center"));
5459
control.addListener("execute", () => osparc.po.POCenterWindow.openWindow(), this);
@@ -134,6 +139,9 @@ qx.Class.define("osparc.navigation.UserMenu", {
134139
this.getChildControl("log-in");
135140
} else {
136141
this.getChildControl("user-center");
142+
if (osparc.data.Permissions.getInstance().isAdmin()) {
143+
this.getChildControl("admin-center");
144+
}
137145
if (osparc.data.Permissions.getInstance().isProductOwner()) {
138146
this.getChildControl("po-center");
139147
}
@@ -172,6 +180,9 @@ qx.Class.define("osparc.navigation.UserMenu", {
172180
this.getChildControl("log-in");
173181
} else {
174182
this.getChildControl("user-center");
183+
if (osparc.data.Permissions.getInstance().isAdmin()) {
184+
this.getChildControl("admin-center");
185+
}
175186
if (osparc.data.Permissions.getInstance().isProductOwner()) {
176187
this.getChildControl("po-center");
177188
}

0 commit comments

Comments
 (0)