Skip to content

Commit f09fb33

Browse files
Merge branch 'master' into introduce-vip-models-pricing-5-part
2 parents 0766313 + 92ddd6c commit f09fb33

File tree

20 files changed

+138
-96
lines changed

20 files changed

+138
-96
lines changed

packages/models-library/src/models_library/api_schemas_webserver/groups.py

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
from typing import Annotated, Any, Self, TypeVar
33

44
from common_library.basic_types import DEFAULT_FACTORY
5+
from models_library.groups import EVERYONE_GROUP_ID
56
from pydantic import (
67
AnyHttpUrl,
78
AnyUrl,
@@ -14,16 +15,16 @@
1415
model_validator,
1516
)
1617

17-
from ..basic_types import IDStr
1818
from ..emails import LowerCaseEmailStr
1919
from ..groups import (
2020
AccessRightsDict,
2121
Group,
22+
GroupID,
2223
GroupMember,
2324
StandardGroupCreate,
2425
StandardGroupUpdate,
2526
)
26-
from ..users import UserID
27+
from ..users import UserID, UserNameID
2728
from ..utils.common_validators import create__check_only_one_is_set__root_validator
2829
from ._base import InputSchema, OutputSchema
2930

@@ -55,7 +56,7 @@ class GroupAccessRights(BaseModel):
5556

5657

5758
class GroupGet(OutputSchema):
58-
gid: int = Field(..., description="the group ID")
59+
gid: GroupID = Field(..., description="the group ID")
5960
label: str = Field(..., description="the group name")
6061
description: str = Field(..., description="the group description")
6162
thumbnail: AnyUrl | None = Field(
@@ -114,7 +115,7 @@ def from_model(cls, group: Group, access_rights: AccessRightsDict) -> Self:
114115
"accessRights": {"read": True, "write": False, "delete": False},
115116
},
116117
{
117-
"gid": "0",
118+
"gid": "1",
118119
"label": "All",
119120
"description": "Open to all users",
120121
"accessRights": {"read": True, "write": True, "delete": True},
@@ -214,7 +215,7 @@ class MyGroupsGet(OutputSchema):
214215
},
215216
],
216217
"all": {
217-
"gid": "0",
218+
"gid": EVERYONE_GROUP_ID,
218219
"label": "All",
219220
"description": "Open to all users",
220221
"accessRights": {"read": True, "write": False, "delete": False},
@@ -228,13 +229,11 @@ class GroupUserGet(BaseModel):
228229
# OutputSchema
229230

230231
# Identifiers
231-
id: Annotated[
232-
str | None, Field(description="the user id", coerce_numbers_to_str=True)
233-
] = None
234-
user_name: Annotated[IDStr, Field(alias="userName")]
232+
id: Annotated[UserID | None, Field(description="the user's id")] = None
233+
user_name: Annotated[UserNameID, Field(alias="userName")]
235234
gid: Annotated[
236-
str | None,
237-
Field(description="the user primary gid", coerce_numbers_to_str=True),
235+
GroupID | None,
236+
Field(description="the user primary gid"),
238237
] = None
239238

240239
# Private Profile
@@ -296,7 +295,7 @@ class GroupUserAdd(InputSchema):
296295
"""
297296

298297
uid: UserID | None = None
299-
user_name: Annotated[IDStr | None, Field(alias="userName")] = None
298+
user_name: Annotated[UserNameID | None, Field(alias="userName")] = None
300299
email: Annotated[
301300
LowerCaseEmailStr | None,
302301
Field(

packages/models-library/src/models_library/groups.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,9 @@
1313
EVERYONE_GROUP_ID: Final[int] = 1
1414

1515

16+
__all__: tuple[str, ...] = ("GroupID",)
17+
18+
1619
class GroupTypeInModel(str, enum.Enum):
1720
"""
1821
standard: standard group, e.g. any group that is not a primary group or special group such as the everyone group

services/static-webserver/client/source/class/osparc/auth/Data.js

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -82,12 +82,9 @@ qx.Class.define("osparc.auth.Data", {
8282
event: "changeUsername",
8383
},
8484

85-
/**
86-
* Email of logged in user, otherwise null
87-
*/
8885
email: {
8986
init: null,
90-
nullable: true,
87+
nullable: true, // email of logged in user, otherwise null
9188
check: "String"
9289
},
9390

services/static-webserver/client/source/class/osparc/auth/Manager.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -241,8 +241,8 @@ qx.Class.define("osparc.auth.Manager", {
241241
authData.set({
242242
email: profile["login"],
243243
username: profile["userName"],
244-
firstName: profile["first_name"] || profile["login"],
245-
lastName: profile["last_name"] || "",
244+
firstName: profile["first_name"],
245+
lastName: profile["last_name"],
246246
expirationDate: "expirationDate" in profile ? new Date(profile["expirationDate"]) : null
247247
});
248248
},

services/static-webserver/client/source/class/osparc/dashboard/CardBase.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -674,7 +674,7 @@ qx.Class.define("osparc.dashboard.CardBase", {
674674
__showBlockedCardFromStatus: function(lockedStatus) {
675675
const status = lockedStatus["status"];
676676
const owner = lockedStatus["owner"];
677-
let toolTip = osparc.utils.Utils.firstsUp(owner["first_name"] || this.tr("A user"), owner["last_name"] || "");
677+
let toolTip = osparc.utils.Utils.firstsUp(owner["first_name"] || this.tr("A user"), owner["last_name"] || ""); // it will be replaced by "userName"
678678
let image = null;
679679
switch (status) {
680680
case "CLOSING":

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,10 @@ qx.Class.define("osparc.data.model.Group", {
104104
return Object.values(this.getGroupMembers()).find(user => user.getUserId() === userId);
105105
},
106106

107+
getGroupMemberByUsername: function(username) {
108+
return Object.values(this.getGroupMembers()).find(user => user.getUsername() === username);
109+
},
110+
107111
getGroupMemberByLogin: function(userEmail) {
108112
return Object.values(this.getGroupMembers()).find(user => user.getEmail() === userEmail);
109113
},

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

Lines changed: 24 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -28,22 +28,27 @@ qx.Class.define("osparc.data.model.User", {
2828
construct: function(userData) {
2929
this.base(arguments);
3030

31-
let label = userData["login"];
31+
let description = "";
3232
if (userData["first_name"]) {
33-
label = qx.lang.String.firstUp(userData["first_name"]);
33+
description = userData["first_name"];
3434
if (userData["last_name"]) {
35-
label += " " + qx.lang.String.firstUp(userData["last_name"]);
35+
description += " " + userData["last_name"];
3636
}
37+
description += " - ";
38+
}
39+
if (userData["login"]) {
40+
description += userData["login"];
3741
}
3842
const thumbnail = osparc.utils.Avatar.emailToThumbnail(userData["login"]);
3943
this.set({
40-
userId: userData["id"],
41-
groupId: userData["gid"],
42-
label: label,
43-
username: userData["username"] || "",
44+
userId: parseInt(userData["id"]),
45+
groupId: parseInt(userData["gid"]),
46+
username: userData["userName"],
4447
firstName: userData["first_name"],
4548
lastName: userData["last_name"],
4649
email: userData["login"],
50+
label: userData["userName"],
51+
description,
4752
thumbnail,
4853
});
4954
},
@@ -70,24 +75,31 @@ qx.Class.define("osparc.data.model.User", {
7075
event: "changeLabel",
7176
},
7277

73-
username: {
78+
description: {
7479
check: "String",
7580
nullable: true,
7681
init: null,
82+
event: "changeDescription",
83+
},
84+
85+
username: {
86+
check: "String",
87+
nullable: false,
88+
init: null,
7789
event: "changeUsername",
7890
},
7991

8092
firstName: {
81-
init: "",
82-
nullable: true,
8393
check: "String",
94+
nullable: true,
95+
init: "",
8496
event: "changeFirstName"
8597
},
8698

8799
lastName: {
88-
init: "",
89-
nullable: true,
90100
check: "String",
101+
nullable: true,
102+
init: "",
91103
event: "changeLastName"
92104
},
93105

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ qx.Class.define("osparc.desktop.MainPageHandler", {
9494
lockedBy = studyData["state"]["locked"]["owner"];
9595
}
9696
if (locked && lockedBy["user_id"] !== osparc.auth.Data.getInstance().getUserId()) {
97-
const msg = `${studyAlias} ${qx.locale.Manager.tr("is already open by")} ${
97+
const msg = `${studyAlias} ${qx.locale.Manager.tr("is already open by")} ${ // it will be replaced "userName"
9898
"first_name" in lockedBy && lockedBy["first_name"] != null ?
9999
lockedBy["first_name"] :
100100
qx.locale.Manager.tr("another user.")

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

Lines changed: 20 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -70,8 +70,8 @@ qx.Class.define("osparc.desktop.organizations.MembersList", {
7070
if (sorted !== 0) {
7171
return sorted;
7272
}
73-
if (("email" in a) && ("email" in b)) {
74-
return a["email"].localeCompare(b["email"]);
73+
if (("label" in a) && ("label" in b)) {
74+
return a["label"].localeCompare(b["label"]);
7575
}
7676
return 0;
7777
}
@@ -105,22 +105,17 @@ qx.Class.define("osparc.desktop.organizations.MembersList", {
105105
alignY: "middle"
106106
}));
107107

108-
const userEmail = new qx.ui.form.TextField().set({
108+
const newMemberUserName = new qx.ui.form.TextField().set({
109109
required: true,
110-
placeholder: this.tr(" New Member's email")
110+
placeholder: this.tr(" New Member's username")
111111
});
112-
hBox.add(userEmail, {
112+
hBox.add(newMemberUserName, {
113113
flex: 1
114114
});
115115

116-
const validator = new qx.ui.form.validation.Manager();
117-
validator.add(userEmail, qx.util.Validate.email());
118-
119116
const addBtn = new qx.ui.form.Button(this.tr("Add"));
120117
addBtn.addListener("execute", function() {
121-
if (validator.validate()) {
122-
this.__addMember(userEmail.getValue());
123-
}
118+
this.__addMember(newMemberUserName.getValue());
124119
}, this);
125120
hBox.add(addBtn);
126121

@@ -154,9 +149,9 @@ qx.Class.define("osparc.desktop.organizations.MembersList", {
154149
ctrl.bindProperty("userId", "model", null, item, id);
155150
ctrl.bindProperty("userId", "key", null, item, id);
156151
ctrl.bindProperty("thumbnail", "thumbnail", null, item, id);
157-
ctrl.bindProperty("name", "title", null, item, id);
152+
ctrl.bindProperty("label", "title", null, item, id);
153+
ctrl.bindProperty("description", "subtitleMD", null, item, id);
158154
ctrl.bindProperty("accessRights", "accessRights", null, item, id);
159-
ctrl.bindProperty("email", "subtitleMD", null, item, id);
160155
ctrl.bindProperty("options", "options", null, item, id);
161156
ctrl.bindProperty("showOptions", "showOptions", null, item, id);
162157
},
@@ -217,23 +212,25 @@ qx.Class.define("osparc.desktop.organizations.MembersList", {
217212
const canIDelete = organization.getAccessRights()["delete"];
218213

219214
const introText = canIWrite ?
220-
this.tr("You can add new members and promote or demote existing ones.") :
215+
this.tr("You can add new members and promote or demote existing ones.<br>In order to add new members, type their username or email if this is public.") :
221216
this.tr("You can't add new members to this Organization. Please contact an Administrator or Manager.");
222217
this.__introLabel.setValue(introText);
223218

224219
this.__memberInvitation.set({
225220
enabled: canIWrite
226221
});
227222

223+
const myGroupId = osparc.auth.Data.getInstance().getGroupId();
228224
const membersList = [];
229225
const groupMembers = organization.getGroupMembers();
230226
Object.values(groupMembers).forEach(groupMember => {
227+
const gid = parseInt(groupMember.getGroupId());
231228
const member = {};
232-
member["userId"] = groupMember.getUserId();
233-
member["groupId"] = groupMember.getGroupId();
229+
member["userId"] = gid === myGroupId ? osparc.auth.Data.getInstance().getUserId() : groupMember.getUserId();
230+
member["groupId"] = gid;
234231
member["thumbnail"] = groupMember.getThumbnail();
235-
member["name"] = groupMember.getLabel();
236-
member["email"] = groupMember.getEmail();
232+
member["label"] = groupMember.getLabel();
233+
member["description"] = gid === myGroupId ? osparc.auth.Data.getInstance().getEmail() : groupMember.getDescription();
237234
member["accessRights"] = groupMember.getAccessRights();
238235
let options = [];
239236
if (canIDelete) {
@@ -287,7 +284,6 @@ qx.Class.define("osparc.desktop.organizations.MembersList", {
287284
}
288285
// Let me go?
289286
const openStudy = osparc.store.Store.getInstance().getCurrentStudy();
290-
const myGroupId = osparc.store.Groups.getInstance().getMyGroupId();
291287
if (
292288
openStudy === null &&
293289
canIWrite &&
@@ -303,16 +299,18 @@ qx.Class.define("osparc.desktop.organizations.MembersList", {
303299
membersList.forEach(member => membersModel.append(qx.data.marshal.Json.createModel(member)));
304300
},
305301

306-
__addMember: async function(orgMemberEmail) {
302+
__addMember: async function(newMemberIdentifier) {
307303
if (this.__currentOrg === null) {
308304
return;
309305
}
310306

311307
const orgId = this.__currentOrg.getGroupId();
312308
const groupsStore = osparc.store.Groups.getInstance();
313-
groupsStore.postMember(orgId, orgMemberEmail)
309+
const isEmail = osparc.utils.Utils.isEmail(newMemberIdentifier);
310+
const request = isEmail ? groupsStore.addMember(orgId, null, newMemberIdentifier) : groupsStore.addMember(orgId, newMemberIdentifier);
311+
request
314312
.then(newMember => {
315-
const text = orgMemberEmail + this.tr(" successfully added");
313+
const text = newMemberIdentifier + this.tr(" successfully added");
316314
osparc.FlashMessenger.getInstance().logAs(text);
317315
this.__reloadOrgMembers();
318316

services/static-webserver/client/source/class/osparc/desktop/wallets/MembersList.js

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -70,8 +70,8 @@ qx.Class.define("osparc.desktop.wallets.MembersList", {
7070
if (sorted !== 0) {
7171
return sorted;
7272
}
73-
if (("email" in a) && ("email" in b)) {
74-
return a["email"].localeCompare(b["email"]);
73+
if (("label" in a) && ("label" in b)) {
74+
return a["label"].localeCompare(b["label"]);
7575
}
7676
return 0;
7777
}
@@ -170,9 +170,9 @@ qx.Class.define("osparc.desktop.wallets.MembersList", {
170170
ctrl.bindProperty("userId", "key", null, item, id);
171171
ctrl.bindProperty("groupId", "gid", null, item, id);
172172
ctrl.bindProperty("thumbnail", "thumbnail", null, item, id);
173-
ctrl.bindProperty("name", "title", null, item, id);
173+
ctrl.bindProperty("label", "title", null, item, id);
174+
ctrl.bindProperty("description", "subtitleMD", null, item, id);
174175
ctrl.bindProperty("accessRights", "accessRights", null, item, id);
175-
ctrl.bindProperty("email", "subtitleMD", null, item, id);
176176
ctrl.bindProperty("options", "options", null, item, id);
177177
ctrl.bindProperty("showOptions", "showOptions", null, item, id);
178178
},
@@ -222,8 +222,8 @@ qx.Class.define("osparc.desktop.wallets.MembersList", {
222222
collaborator["userId"] = gid === myGroupId ? osparc.auth.Data.getInstance().getUserId() : collab.getUserId();
223223
collaborator["groupId"] = collab.getGroupId();
224224
collaborator["thumbnail"] = collab.getThumbnail();
225-
collaborator["name"] = collab.getLabel();
226-
collaborator["email"] = gid === myGroupId ? osparc.auth.Data.getInstance().getEmail() : collab.getEmail();
225+
collaborator["label"] = collab.getLabel();
226+
collaborator["description"] = gid === myGroupId ? osparc.auth.Data.getInstance().getEmail() : collab.getDescription();
227227
collaborator["accessRights"] = {
228228
read: accessRights["read"],
229229
write: accessRights["write"],

0 commit comments

Comments
 (0)