Skip to content

Commit 19b60cc

Browse files
authored
🎨 [Frontend] Enh: User Account UI (#8361)
1 parent d0d210d commit 19b60cc

File tree

7 files changed

+250
-91
lines changed

7 files changed

+250
-91
lines changed

services/static-webserver/client/source/class/osparc/theme/Appearance.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1066,8 +1066,8 @@ qx.Theme.define("osparc.theme.Appearance", {
10661066
include: "form-button",
10671067
style: state => ({
10681068
decorator: state.hovered || state.focused ? "form-button-danger-hover" : "form-button-danger",
1069-
backgroundColor: state.hovered || state.focused ? "default-button-hover-background" : "error",
1070-
textColor: "black",
1069+
backgroundColor: state.hovered || state.focused || state.disabled ? "default-button-hover-background" : "error",
1070+
textColor: state.disabled ? "text": "black",
10711071
})
10721072
},
10731073

services/static-webserver/client/source/class/osparc/ui/basic/UserThumbnail.js

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -49,9 +49,7 @@ qx.Class.define("osparc.ui.basic.UserThumbnail", {
4949

5050
__openUserDetails: function() {
5151
if (this.getUser()) {
52-
const userDetails = new osparc.user.UserDetails(this.getUser().getGroupId());
53-
userDetails.center();
54-
userDetails.open();
52+
osparc.user.UserAccountWindow.openWindow(this.getUser().getGroupId());
5553
}
5654
},
5755
}
Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
/* ************************************************************************
2+
3+
osparc - the simcore frontend
4+
5+
https://osparc.io
6+
7+
Copyright:
8+
2025 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.user.UserAccount", {
19+
extend: osparc.ui.window.TabbedView,
20+
21+
construct: function(userGroupId) {
22+
this.base(arguments);
23+
24+
this.set({
25+
padding: 10,
26+
});
27+
28+
this.getChildControl("thumbnail");
29+
const profilePage = this.getChildControl("profile-page");
30+
const extras = this.getChildControl("extras-page");
31+
this.bind("user", profilePage, "user");
32+
this.bind("extras", extras, "extras");
33+
34+
this.setUserGroupId(userGroupId);
35+
},
36+
37+
properties: {
38+
userGroupId: {
39+
check: "Number",
40+
init: null,
41+
nullable: false,
42+
apply: "__applyUserGroupId",
43+
},
44+
45+
user: {
46+
check: "osparc.data.model.User",
47+
init: null,
48+
nullable: false,
49+
event: "changeUser",
50+
},
51+
52+
extras: {
53+
check: "Object",
54+
init: null,
55+
nullable: false,
56+
event: "changeExtras",
57+
},
58+
},
59+
60+
events: {
61+
"updateCaption": "qx.event.type.Data",
62+
"closeWindow": "qx.event.type.Event",
63+
},
64+
65+
statics: {
66+
THUMBNAIL_SIZE: 90,
67+
},
68+
69+
members: {
70+
_createChildControlImpl: function(id) {
71+
let control;
72+
switch (id) {
73+
case "thumbnail":
74+
control = new osparc.ui.basic.Thumbnail(null, this.self().THUMBNAIL_SIZE, this.self().THUMBNAIL_SIZE).set({
75+
width: this.self().THUMBNAIL_SIZE,
76+
height: this.self().THUMBNAIL_SIZE,
77+
marginBottom: 10,
78+
});
79+
control.getChildControl("image").set({
80+
anonymous: true,
81+
decorator: "rounded",
82+
});
83+
this.addWidgetToTabs(control);
84+
break;
85+
case "profile-page":
86+
control = new osparc.user.UserProfile();
87+
this.addTab("Profile", "", control);
88+
break;
89+
case "extras-page":
90+
control = new osparc.user.UserExtras();
91+
this.addTab("Extras", "", control);
92+
break;
93+
}
94+
return control || this.base(arguments, id);
95+
},
96+
97+
__applyUserGroupId: function(userGroupId) {
98+
const params = {
99+
url: {
100+
gId: userGroupId
101+
}
102+
};
103+
osparc.data.Resources.fetch("poUsers", "searchByGroupId", params)
104+
.then(usersData => {
105+
if (usersData.length === 1) {
106+
const userData = usersData[0];
107+
108+
const user = new osparc.data.model.User(userData);
109+
user.setContactData(userData);
110+
// remove the displayed properties from the contact info
111+
Object.keys(qx.util.PropertyUtil.getProperties(osparc.data.model.User)).forEach(prop => delete userData[prop]);
112+
const extras = osparc.utils.Utils.convertKeysToTitles(userData);
113+
114+
this.fireDataEvent("updateCaption", user.getUserName());
115+
this.getChildControl("thumbnail").setSource(user.createThumbnail(this.self().THUMBNAIL_SIZE));
116+
this.setUser(user);
117+
this.setExtras(extras);
118+
}
119+
})
120+
.catch(err => {
121+
osparc.FlashMessenger.logError(err);
122+
console.error(err);
123+
this.fireEvent("closeWindow");
124+
});
125+
},
126+
}
127+
});
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
/* ************************************************************************
2+
3+
osparc - the simcore frontend
4+
5+
https://osparc.io
6+
7+
Copyright:
8+
2025 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.user.UserAccountWindow", {
19+
extend: osparc.ui.window.TabbedWindow,
20+
21+
construct: function(userGroupId) {
22+
this.base(arguments, "user-account-"+userGroupId, this.tr("User Account"));
23+
24+
this.set({
25+
width: osparc.user.UserAccountWindow.WIDTH,
26+
height: osparc.user.UserAccountWindow.HEIGHT,
27+
});
28+
29+
const userAccount = new osparc.user.UserAccount(userGroupId);
30+
userAccount.addListener("updateCaption", e => this.setCaption(e.getData()));
31+
userAccount.addListener("closeWindow", () => this.close(), this);
32+
this._setTabbedView(userAccount);
33+
},
34+
35+
statics: {
36+
WIDTH: 500,
37+
HEIGHT: 500,
38+
39+
openWindow: function(userGroupId) {
40+
const userAccountWindow = new osparc.user.UserAccountWindow(userGroupId);
41+
userAccountWindow.center();
42+
userAccountWindow.open();
43+
return userAccountWindow;
44+
},
45+
},
46+
});
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
/* ************************************************************************
2+
3+
osparc - the simcore frontend
4+
5+
https://osparc.io
6+
7+
Copyright:
8+
2025 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.user.UserExtras", {
19+
extend: qx.ui.core.Widget,
20+
21+
construct: function() {
22+
this.base(arguments);
23+
24+
this._setLayout(new qx.ui.layout.VBox(10));
25+
},
26+
27+
properties: {
28+
extras: {
29+
check: "Object",
30+
init: null,
31+
nullable: true,
32+
event: "changeExtras",
33+
apply: "__applyExtras",
34+
}
35+
},
36+
37+
members: {
38+
__applyExtras: function(extras) {
39+
if (!extras) {
40+
return;
41+
}
42+
43+
for (const key in extras) {
44+
const value = extras[key];
45+
if (osparc.utils.Utils.isDateLike(value)) {
46+
extras[key] = osparc.utils.Utils.formatDateAndTime(new Date(value));
47+
}
48+
}
49+
50+
const jsonViewer = new osparc.widget.JsonFormatterWidget(extras);
51+
const scroll = new qx.ui.container.Scroll();
52+
scroll.add(jsonViewer);
53+
this._add(scroll, {
54+
flex: 1
55+
});
56+
},
57+
}
58+
});

0 commit comments

Comments
 (0)