diff --git a/services/static-webserver/client/source/class/osparc/auth/Data.js b/services/static-webserver/client/source/class/osparc/auth/Data.js index cda4da711d40..55668cbd5668 100644 --- a/services/static-webserver/client/source/class/osparc/auth/Data.js +++ b/services/static-webserver/client/source/class/osparc/auth/Data.js @@ -75,11 +75,11 @@ qx.Class.define("osparc.auth.Data", { check: "Number" }, - username: { + userName: { check: "String", init: null, nullable: false, - event: "changeUsername", + event: "changeUserName", }, email: { @@ -139,12 +139,12 @@ qx.Class.define("osparc.auth.Data", { return osparc.utils.Utils.cookie.getCookie("user") === "logout"; }, - getFriendlyUsername: function() { + getFriendlyUserName: function() { const firstName = this.getFirstName(); if (firstName) { return firstName; } - return this.getUsername(); + return this.getUserName(); }, getFullName: function() { diff --git a/services/static-webserver/client/source/class/osparc/auth/Manager.js b/services/static-webserver/client/source/class/osparc/auth/Manager.js index 10d7548a5713..5936e015e07b 100644 --- a/services/static-webserver/client/source/class/osparc/auth/Manager.js +++ b/services/static-webserver/client/source/class/osparc/auth/Manager.js @@ -258,7 +258,7 @@ qx.Class.define("osparc.auth.Manager", { const authData = osparc.auth.Data.getInstance(); authData.set({ email: profile["login"], - username: profile["userName"], + userName: profile["userName"], firstName: profile["first_name"], lastName: profile["last_name"], expirationDate: profile["expirationDate"] ? new Date(profile["expirationDate"]) : null diff --git a/services/static-webserver/client/source/class/osparc/auth/ui/LoginView.js b/services/static-webserver/client/source/class/osparc/auth/ui/LoginView.js index 2bca1dde1f90..59b92fde83b0 100644 --- a/services/static-webserver/client/source/class/osparc/auth/ui/LoginView.js +++ b/services/static-webserver/client/source/class/osparc/auth/ui/LoginView.js @@ -73,7 +73,7 @@ qx.Class.define("osparc.auth.ui.LoginView", { const email = new qx.ui.form.TextField().set({ required: true }); - email.getContentElement().setAttribute("autocomplete", "username"); + email.getContentElement().setAttribute("autocomplete", "userName"); osparc.utils.Utils.setIdToWidget(email, "loginUserEmailFld"); this._form.add(email, " Email", qx.util.Validate.email(), "email"); const focusEmail = () => { diff --git a/services/static-webserver/client/source/class/osparc/dashboard/CardBase.js b/services/static-webserver/client/source/class/osparc/dashboard/CardBase.js index d2ceabbcfed4..910ddca5cf24 100644 --- a/services/static-webserver/client/source/class/osparc/dashboard/CardBase.js +++ b/services/static-webserver/client/source/class/osparc/dashboard/CardBase.js @@ -914,13 +914,13 @@ qx.Class.define("osparc.dashboard.CardBase", { const currentUserGroupIds = osparc.study.Utils.state.getCurrentGroupIds(state); const usersStore = osparc.store.Users.getInstance(); const userPromises = currentUserGroupIds.map(userGroupId => usersStore.getUser(userGroupId)); - const usernames = []; + const userNames = []; let toolTip = ""; let image = null; Promise.all(userPromises) .then(usersResult => { usersResult.forEach(user => { - usernames.push(user.getUsername()); + userNames.push(user.getUserName()); }); }) .catch(error => { @@ -952,8 +952,8 @@ qx.Class.define("osparc.dashboard.CardBase", { image = "@FontAwesome5Solid/lock/"; break; } - usernames.forEach(username => { - toolTip += "
" + username; + userNames.forEach(userName => { + toolTip += "
" + userName; }); this.__showBlockedCard(image, toolTip); }); diff --git a/services/static-webserver/client/source/class/osparc/data/Resources.js b/services/static-webserver/client/source/class/osparc/data/Resources.js index 60573e3115fd..b521517c0fa4 100644 --- a/services/static-webserver/client/source/class/osparc/data/Resources.js +++ b/services/static-webserver/client/source/class/osparc/data/Resources.js @@ -1131,10 +1131,14 @@ qx.Class.define("osparc.data.Resources", { }, "poUsers": { endpoints: { - search: { + searchByEmail: { method: "GET", url: statics.API + "/admin/user-accounts:search?email={email}" }, + searchByGroupId: { + method: "GET", + url: statics.API + "/admin/user-accounts:search?primary_group_id={gId}" + }, getPendingUsers: { method: "GET", url: statics.API + "/admin/user-accounts?review_status=PENDING" diff --git a/services/static-webserver/client/source/class/osparc/data/model/Conversation.js b/services/static-webserver/client/source/class/osparc/data/model/Conversation.js index 01a322c0c974..1d168b736e87 100644 --- a/services/static-webserver/client/source/class/osparc/data/model/Conversation.js +++ b/services/static-webserver/client/source/class/osparc/data/model/Conversation.js @@ -304,7 +304,7 @@ qx.Class.define("osparc.data.model.Conversation", { const extraContext = this.getExtraContext() || {}; extraContext["appointment"] = appointment ? appointment.toISOString() : null; // OM: Supporters are not allowed to patch the conversation metadata yet - const backendAllowsPatch = osparc.store.Products.getInstance().amIASupportUser() ? false : true; + const backendAllowsPatch = osparc.store.Groups.getInstance().amIASupportUser() ? false : true; if (backendAllowsPatch) { return osparc.store.ConversationsSupport.getInstance().patchExtraContext(this.getConversationId(), extraContext) .then(() => { diff --git a/services/static-webserver/client/source/class/osparc/data/model/Group.js b/services/static-webserver/client/source/class/osparc/data/model/Group.js index 11cc663337da..3153c95e0dc1 100644 --- a/services/static-webserver/client/source/class/osparc/data/model/Group.js +++ b/services/static-webserver/client/source/class/osparc/data/model/Group.js @@ -104,8 +104,8 @@ qx.Class.define("osparc.data.model.Group", { return Object.values(this.getGroupMembers()).find(user => user.getUserId() === userId); }, - getGroupMemberByUsername: function(username) { - return Object.values(this.getGroupMembers()).find(user => user.getUsername() === username); + getGroupMemberByUserName: function(userName) { + return Object.values(this.getGroupMembers()).find(user => user.getUserName() === userName); }, getGroupMemberByLogin: function(userEmail) { diff --git a/services/static-webserver/client/source/class/osparc/data/model/User.js b/services/static-webserver/client/source/class/osparc/data/model/User.js index 595223ff4aea..2e3c2451ce1f 100644 --- a/services/static-webserver/client/source/class/osparc/data/model/User.js +++ b/services/static-webserver/client/source/class/osparc/data/model/User.js @@ -30,7 +30,7 @@ qx.Class.define("osparc.data.model.User", { const userId = ("id" in userData) ? parseInt(userData["id"]) : parseInt(userData["userId"]); const groupId = ("gid" in userData) ? parseInt(userData["gid"]) : parseInt(userData["groupId"]); - const username = userData["userName"] || "-"; + const userName = userData["userName"] || "-"; const email = ("login" in userData) ? userData["login"] : userData["email"]; let firstName = ""; if (userData["first_name"]) { @@ -48,11 +48,11 @@ qx.Class.define("osparc.data.model.User", { this.set({ userId, groupId, - username, + userName, firstName, lastName, email, - phoneNumber: userData["phone"] || null, + phone: userData["phone"] || null, }); const description = osparc.data.model.User.userDataToDescription(firstName, lastName, email); @@ -62,18 +62,11 @@ qx.Class.define("osparc.data.model.User", { }); if (userData["contact"]) { - const contact = userData["contact"]; - this.set({ - institution: contact["institution"] || null, - address: contact["address"] || null, - city: contact["city"] || null, - state: contact["state"] || null, - country: contact["country"] || null, - postalCode: contact["postalCode"] || null, - }); + const contactData = userData["contact"]; + this.setContactData(contactData); } - // create the thumbnail after setting email and username + // create the thumbnail after setting email and userName this.set({ thumbnail: this.createThumbnail(), }); @@ -108,11 +101,11 @@ qx.Class.define("osparc.data.model.User", { event: "changeDescription", }, - username: { + userName: { check: "String", nullable: false, init: null, - event: "changeUsername", + event: "changeUserName", }, firstName: { @@ -136,11 +129,11 @@ qx.Class.define("osparc.data.model.User", { event: "changeEmail", }, - phoneNumber: { + phone: { check: "String", nullable: true, init: null, - event: "changePhoneNumber" + event: "changePhone", }, thumbnail: { @@ -212,11 +205,22 @@ qx.Class.define("osparc.data.model.User", { members: { createThumbnail: function(size) { - return osparc.utils.Avatar.emailToThumbnail(this.getEmail(), this.getUsername(), size); + return osparc.utils.Avatar.emailToThumbnail(this.getEmail(), this.getUserName(), size); }, getFullName: function() { return this.self().concatFullName(this.getFirstName(), this.getLastName()); }, + + setContactData: function(contactData) { + this.set({ + institution: contactData["institution"] || null, + address: contactData["address"] || null, + city: contactData["city"] || null, + state: contactData["state"] || null, + country: contactData["country"] || null, + postalCode: contactData["postalCode"] || null, + }); + }, }, }); diff --git a/services/static-webserver/client/source/class/osparc/desktop/account/MyAccount.js b/services/static-webserver/client/source/class/osparc/desktop/account/MyAccount.js index 619ad99a6d14..7c70607500ed 100644 --- a/services/static-webserver/client/source/class/osparc/desktop/account/MyAccount.js +++ b/services/static-webserver/client/source/class/osparc/desktop/account/MyAccount.js @@ -56,11 +56,11 @@ qx.Class.define("osparc.desktop.account.MyAccount", { if (!userData) { userData = osparc.auth.Data.getInstance(); } - const username = userData.getUsername(); + const userName = userData.getUserName(); const email = userData.getEmail(); const avatarSize = 80; const img = new qx.ui.basic.Image().set({ - source: osparc.utils.Avatar.emailToThumbnail(email, username, avatarSize), + source: osparc.utils.Avatar.emailToThumbnail(email, userName, avatarSize), maxWidth: avatarSize, maxHeight: avatarSize, scale: true, @@ -71,12 +71,12 @@ qx.Class.define("osparc.desktop.account.MyAccount", { }); layout.add(img); - const usernameLabel = new qx.ui.basic.Label().set({ + const userNameLabel = new qx.ui.basic.Label().set({ font: "text-14", alignX: "center" }); - userData.bind("username", usernameLabel, "value"); - layout.add(usernameLabel); + userData.bind("userName", userNameLabel, "value"); + layout.add(userNameLabel); const fullNameLabel = new qx.ui.basic.Label().set({ font: "text-13", diff --git a/services/static-webserver/client/source/class/osparc/desktop/account/ProfilePage.js b/services/static-webserver/client/source/class/osparc/desktop/account/ProfilePage.js index e08e0f6241d0..b77bc4a5155b 100644 --- a/services/static-webserver/client/source/class/osparc/desktop/account/ProfilePage.js +++ b/services/static-webserver/client/source/class/osparc/desktop/account/ProfilePage.js @@ -19,7 +19,7 @@ /** * User profile in preferences dialog * - * - first name, last name, username, email + * - first name, last name, userName, email * */ @@ -43,7 +43,7 @@ qx.Class.define("osparc.desktop.account.ProfilePage", { this.__userProfileData = {}; this.__userPrivacyData = {}; - this.__fetchProfile(); + this.__fetchMyProfile(); }, statics: { @@ -80,7 +80,7 @@ qx.Class.define("osparc.desktop.account.ProfilePage", { __personalInfoModel: null, __personalInfoRenderer: null, - __fetchProfile: function() { + __fetchMyProfile: function() { this.__userProfileRenderer.setEnabled(false); this.__privacyRenderer.setEnabled(false); this.__personalInfoRenderer.setEnabled(false); @@ -100,7 +100,7 @@ qx.Class.define("osparc.desktop.account.ProfilePage", { if (data) { this.__userProfileData = data; this.__userProfileModel.set({ - "username": data["userName"] || "", + "userName": data["userName"] || "", "firstName": data["first_name"] || "", "lastName": data["last_name"] || "", "email": data["login"], @@ -130,7 +130,7 @@ qx.Class.define("osparc.desktop.account.ProfilePage", { if (privacyData) { this.__userPrivacyData = privacyData; this.__userPrivacyModel.set({ - "hideUsername": "hideUsername" in privacyData ? privacyData["hideUsername"] : false, + "hideUserName": "hideUserName" in privacyData ? privacyData["hideUserName"] : false, "hideFullname": "hideFullname" in privacyData ? privacyData["hideFullname"] : true, "hideEmail": "hideEmail" in privacyData ? privacyData["hideEmail"] : true, }); @@ -145,7 +145,7 @@ qx.Class.define("osparc.desktop.account.ProfilePage", { } const pos = this.self().PROFILE.POS; const widgets = { - [pos.USERNAME]: createImage(this.__userPrivacyModel.getHideUsername() ? hiddenIcon : visibleIcon), + [pos.USERNAME]: createImage(this.__userPrivacyModel.getHideUserName() ? hiddenIcon : visibleIcon), [pos.FIRST_NAME]: createImage(this.__userPrivacyModel.getHideFullname() ? hiddenIcon : visibleIcon), [pos.LAST_NAME]: createImage(this.__userPrivacyModel.getHideFullname() ? hiddenIcon : visibleIcon), [pos.EMAIL]: createImage(this.__userPrivacyModel.getHideEmail() ? hiddenIcon : visibleIcon), @@ -174,8 +174,8 @@ qx.Class.define("osparc.desktop.account.ProfilePage", { // layout const box = this.self().createSectionBox(this.tr("User")); - const username = new qx.ui.form.TextField().set({ - placeholder: this.tr("username") + const userName = new qx.ui.form.TextField().set({ + placeholder: this.tr("userName") }); const firstName = new qx.ui.form.TextField().set({ @@ -196,12 +196,12 @@ qx.Class.define("osparc.desktop.account.ProfilePage", { }); const profileForm = this.__userProfileForm = new qx.ui.form.Form(); - profileForm.add(username, "Username", null, "username"); + profileForm.add(userName, "UserName", null, "userName"); profileForm.add(firstName, "First Name", null, "firstName"); profileForm.add(lastName, "Last Name", null, "lastName"); profileForm.add(email, "Email", null, "email"); if (osparc.store.StaticInfo.is2FARequired()) { - profileForm.add(phoneNumber, "Phone Number", null, "phoneNumber"); + profileForm.add(phoneNumber, "Phone Number", null, "phone"); } this.__userProfileRenderer = new osparc.ui.form.renderer.SingleWithWidget(profileForm); box.add(this.__userProfileRenderer); @@ -225,7 +225,7 @@ qx.Class.define("osparc.desktop.account.ProfilePage", { // binding to a model const raw = { - "username": "", + "userName": "", "firstName": "", "lastName": "", "email": "", @@ -236,7 +236,7 @@ qx.Class.define("osparc.desktop.account.ProfilePage", { const model = this.__userProfileModel = qx.data.marshal.Json.createModel(raw); const controller = new qx.data.controller.Object(model); - controller.addTarget(username, "value", "username", true); + controller.addTarget(userName, "value", "userName", true); controller.addTarget(email, "value", "email", true); controller.addTarget(firstName, "value", "firstName", true, null, { converter: function(data) { @@ -279,8 +279,8 @@ qx.Class.define("osparc.desktop.account.ProfilePage", { } const patchData = {}; - if (this.__userProfileData["userName"] !== model.getUsername()) { - patchData["userName"] = model.getUsername(); + if (this.__userProfileData["userName"] !== model.getUserName()) { + patchData["userName"] = model.getUserName(); } if (this.__userProfileData["first_name"] !== model.getFirstName()) { patchData["first_name"] = model.getFirstName(); @@ -310,13 +310,13 @@ qx.Class.define("osparc.desktop.account.ProfilePage", { }); const profileFields = [ - username, + userName, firstName, lastName, ] const valueChanged = () => { const anyChanged = - username.getValue() !== this.__userProfileData["userName"] || + userName.getValue() !== this.__userProfileData["userName"] || firstName.getValue() !== this.__userProfileData["first_name"] || lastName.getValue() !== this.__userProfileData["last_name"]; updateProfileBtn.setEnabled(anyChanged); @@ -329,7 +329,7 @@ qx.Class.define("osparc.desktop.account.ProfilePage", { __createPrivacySection: function() { // binding to a model const defaultModel = { - "hideUsername": false, + "hideUserName": false, "hideFullname": true, "hideEmail": true, }; @@ -341,8 +341,8 @@ qx.Class.define("osparc.desktop.account.ProfilePage", { const label = osparc.ui.window.TabbedView.createHelpLabel(this.tr("Choose what others see.")); box.add(label); - const hideUsername = new qx.ui.form.CheckBox().set({ - value: defaultModel.hideUsername + const hideUserName = new qx.ui.form.CheckBox().set({ + value: defaultModel.hideUserName }); const hideFullname = new qx.ui.form.CheckBox().set({ value: defaultModel.hideFullname @@ -352,14 +352,14 @@ qx.Class.define("osparc.desktop.account.ProfilePage", { }); const privacyForm = new qx.ui.form.Form(); - privacyForm.add(hideUsername, "Hide Username", null, "hideUsername"); + privacyForm.add(hideUserName, "Hide UserName", null, "hideUserName"); privacyForm.add(hideFullname, "Hide Full Name", null, "hideFullname"); privacyForm.add(hideEmail, "Hide Email", null, "hideEmail"); this.__privacyRenderer = new qx.ui.form.renderer.Single(privacyForm); box.add(this.__privacyRenderer); const privacyModelCtrl = new qx.data.controller.Object(privacyModel); - privacyModelCtrl.addTarget(hideUsername, "value", "hideUsername", true); + privacyModelCtrl.addTarget(hideUserName, "value", "hideUserName", true); privacyModelCtrl.addTarget(hideFullname, "value", "hideFullname", true); privacyModelCtrl.addTarget(hideEmail, "value", "hideEmail", true); @@ -379,8 +379,8 @@ qx.Class.define("osparc.desktop.account.ProfilePage", { const patchData = { "privacy": {} }; - if (this.__userPrivacyData["hideUsername"] !== privacyModel.getHideUsername()) { - patchData["privacy"]["hideUsername"] = privacyModel.getHideUsername(); + if (this.__userPrivacyData["hideUserName"] !== privacyModel.getHideUserName()) { + patchData["privacy"]["hideUserName"] = privacyModel.getHideUserName(); } if (this.__userPrivacyData["hideFullname"] !== privacyModel.getHideFullname()) { patchData["privacy"]["hideFullname"] = privacyModel.getHideFullname(); @@ -429,13 +429,13 @@ qx.Class.define("osparc.desktop.account.ProfilePage", { box.add(optOutMessage); const privacyFields = [ - hideUsername, + hideUserName, hideFullname, hideEmail, ] const valueChanged = () => { const anyChanged = - hideUsername.getValue() !== this.__userPrivacyData["hideUsername"] || + hideUserName.getValue() !== this.__userPrivacyData["hideUserName"] || hideFullname.getValue() !== this.__userPrivacyData["hideFullname"] || hideEmail.getValue() !== this.__userPrivacyData["hideEmail"]; updatePrivacyBtn.setEnabled(anyChanged); @@ -693,7 +693,7 @@ qx.Class.define("osparc.desktop.account.ProfilePage", { }); verifyPhoneNumberView.addListener("done", () => { win.close(); - this.__fetchProfile(); + this.__fetchMyProfile(); }, this); }, } diff --git a/services/static-webserver/client/source/class/osparc/desktop/organizations/MembersList.js b/services/static-webserver/client/source/class/osparc/desktop/organizations/MembersList.js index 9321319958ad..c636ab36df21 100644 --- a/services/static-webserver/client/source/class/osparc/desktop/organizations/MembersList.js +++ b/services/static-webserver/client/source/class/osparc/desktop/organizations/MembersList.js @@ -110,7 +110,7 @@ qx.Class.define("osparc.desktop.organizations.MembersList", { .then(values => { values.forEach(user => { if (user) { - this.__addMember(user.getUsername()); + this.__addMember(user.getUserName()); } }); }) diff --git a/services/static-webserver/client/source/class/osparc/info/FunctionLarge.js b/services/static-webserver/client/source/class/osparc/info/FunctionLarge.js index 103dad7c5e88..941a8040f137 100644 --- a/services/static-webserver/client/source/class/osparc/info/FunctionLarge.js +++ b/services/static-webserver/client/source/class/osparc/info/FunctionLarge.js @@ -61,14 +61,12 @@ qx.Class.define("osparc.info.FunctionLarge", { "Default Inputs": this.getFunction().getDefaultInputs(), "Outputs": this.getFunction().getOutputSchema()["schema_content"], }; - const divId = "function-info-viewer"; - const htmlEmbed = osparc.wrapper.JsonFormatter.getInstance().createContainer(divId); - vBox.add(htmlEmbed, { + const jsonViewer = new osparc.widget.JsonFormatterWidget(info); + const scroll = new qx.ui.container.Scroll(); + scroll.add(jsonViewer); + vBox.add(scroll, { flex: 1 }); - vBox.addListener("appear", () => { - osparc.wrapper.JsonFormatter.getInstance().setJson(info, divId); - }); // Copy Id button const text = "Function Id"; diff --git a/services/static-webserver/client/source/class/osparc/io/rest/AbstractResource.js b/services/static-webserver/client/source/class/osparc/io/rest/AbstractResource.js index 2fcc25e653c2..24a402fe1462 100644 --- a/services/static-webserver/client/source/class/osparc/io/rest/AbstractResource.js +++ b/services/static-webserver/client/source/class/osparc/io/rest/AbstractResource.js @@ -26,8 +26,8 @@ qx.Class.define("osparc.io.rest.AbstractResource", { API: "/v0", AUTHENTICATION: null, - setAutheticationHeader: function(usernameOrToken, password=null) { - osparc.io.rest.AbstractResource.AUTHENTICATION = new qx.io.request.authentication.Basic(usernameOrToken, password); + setAutheticationHeader: function(userNameOrToken, password=null) { + osparc.io.rest.AbstractResource.AUTHENTICATION = new qx.io.request.authentication.Basic(userNameOrToken, password); } }, diff --git a/services/static-webserver/client/source/class/osparc/io/rest/Resource.js b/services/static-webserver/client/source/class/osparc/io/rest/Resource.js index ec5225e084ce..3f6203f62beb 100644 --- a/services/static-webserver/client/source/class/osparc/io/rest/Resource.js +++ b/services/static-webserver/client/source/class/osparc/io/rest/Resource.js @@ -54,8 +54,8 @@ qx.Class.define("osparc.io.rest.Resource", { statics: { AUTHENTICATION: null, - setAutheticationHeader: function(usernameOrToken, password=null) { - osparc.io.rest.Resource.AUTHENTICATION = new qx.io.request.authentication.Basic(usernameOrToken, password); + setAutheticationHeader: function(userNameOrToken, password=null) { + osparc.io.rest.Resource.AUTHENTICATION = new qx.io.request.authentication.Basic(userNameOrToken, password); } }, diff --git a/services/static-webserver/client/source/class/osparc/jobs/Info.js b/services/static-webserver/client/source/class/osparc/jobs/Info.js index 2ae9a811eed5..2757a5cf84d0 100644 --- a/services/static-webserver/client/source/class/osparc/jobs/Info.js +++ b/services/static-webserver/client/source/class/osparc/jobs/Info.js @@ -24,14 +24,12 @@ qx.Class.define("osparc.jobs.Info", { this._setLayout(new qx.ui.layout.VBox()); - const divId = "job-info-viewer"; - const htmlEmbed = osparc.wrapper.JsonFormatter.getInstance().createContainer(divId); - this._add(htmlEmbed, { + const jsonViewer = new osparc.widget.JsonFormatterWidget(info); + const scroll = new qx.ui.container.Scroll(); + scroll.add(jsonViewer); + this._add(scroll, { flex: 1 }); - this.addListener("appear", () => { - osparc.wrapper.JsonFormatter.getInstance().setJson(info, divId); - }); }, statics: { @@ -42,21 +40,4 @@ qx.Class.define("osparc.jobs.Info", { return win; } }, - - members: { - _createChildControlImpl: function(id) { - let control; - switch (id) { - case "job-info-viewer": { - control = new osparc.ui.basic.JsonTreeWidget(); - const container = new qx.ui.container.Scroll(); - container.add(control); - this._add(container); - break; - } - } - - return control || this.base(arguments, id); - }, - } }) diff --git a/services/static-webserver/client/source/class/osparc/navigation/UserMenuButton.js b/services/static-webserver/client/source/class/osparc/navigation/UserMenuButton.js index 777834d2739e..355b1c502d66 100644 --- a/services/static-webserver/client/source/class/osparc/navigation/UserMenuButton.js +++ b/services/static-webserver/client/source/class/osparc/navigation/UserMenuButton.js @@ -51,7 +51,7 @@ qx.Class.define("osparc.navigation.UserMenuButton", { const preferencesSettings = osparc.Preferences.getInstance(); preferencesSettings.addListener("changeCreditsWarningThreshold", () => this.__updateHaloColor()); - const myUsername = authData.getUsername() || "Username"; + const myUserName = authData.getUserName() || "UserName"; const myEmail = authData.getEmail() || "bizzy@itis.ethz.ch"; const icon = this.getChildControl("icon"); authData.bind("role", this, "icon", { @@ -65,7 +65,7 @@ qx.Class.define("osparc.navigation.UserMenuButton", { icon.getContentElement().setStyles({ "margin-left": "-4px" }); - return osparc.utils.Avatar.emailToThumbnail(myEmail, myUsername, 32); + return osparc.utils.Avatar.emailToThumbnail(myEmail, myUserName, 32); } }); }, diff --git a/services/static-webserver/client/source/class/osparc/po/Users.js b/services/static-webserver/client/source/class/osparc/po/Users.js index de8164957dda..c34850e11e54 100644 --- a/services/static-webserver/client/source/class/osparc/po/Users.js +++ b/services/static-webserver/client/source/class/osparc/po/Users.js @@ -83,7 +83,7 @@ qx.Class.define("osparc.po.Users", { email: userEmail.getValue() } }; - osparc.data.Resources.fetch("poUsers", "search", params) + osparc.data.Resources.fetch("poUsers", "searchByEmail", params) .then(data => { findingStatus.setValue(data.length + this.tr(" user(s) found")); this.__populateFoundUsersLayout(data); diff --git a/services/static-webserver/client/source/class/osparc/product/quickStart/s4l/Welcome.js b/services/static-webserver/client/source/class/osparc/product/quickStart/s4l/Welcome.js index 8e4386e22586..c3daa219a7b3 100644 --- a/services/static-webserver/client/source/class/osparc/product/quickStart/s4l/Welcome.js +++ b/services/static-webserver/client/source/class/osparc/product/quickStart/s4l/Welcome.js @@ -55,7 +55,7 @@ qx.Class.define("osparc.product.quickStart.s4l.Welcome", { }); content.add(intro1); - const welcomeText = this.tr("Welcome onboard ") + osparc.utils.Utils.capitalize(osparc.auth.Data.getInstance().getFriendlyUsername()) + ","; + const welcomeText = this.tr("Welcome onboard ") + osparc.utils.Utils.capitalize(osparc.auth.Data.getInstance().getFriendlyUserName()) + ","; const welcome = osparc.product.quickStart.Utils.createLabel(welcomeText); content.add(welcome); diff --git a/services/static-webserver/client/source/class/osparc/product/quickStart/s4lacad/Welcome.js b/services/static-webserver/client/source/class/osparc/product/quickStart/s4lacad/Welcome.js index 49f5fa773dc6..68772ee61c42 100644 --- a/services/static-webserver/client/source/class/osparc/product/quickStart/s4lacad/Welcome.js +++ b/services/static-webserver/client/source/class/osparc/product/quickStart/s4lacad/Welcome.js @@ -55,7 +55,7 @@ qx.Class.define("osparc.product.quickStart.s4lacad.Welcome", { }); content.add(intro1); - const welcomeText = this.tr("Welcome onboard ") + osparc.utils.Utils.capitalize(osparc.auth.Data.getInstance().getFriendlyUsername()) + ","; + const welcomeText = this.tr("Welcome onboard ") + osparc.utils.Utils.capitalize(osparc.auth.Data.getInstance().getFriendlyUserName()) + ","; const welcome = osparc.product.quickStart.Utils.createLabel(welcomeText); content.add(welcome); diff --git a/services/static-webserver/client/source/class/osparc/product/quickStart/s4llite/Welcome.js b/services/static-webserver/client/source/class/osparc/product/quickStart/s4llite/Welcome.js index 47fd5da29ab4..4312704419a6 100644 --- a/services/static-webserver/client/source/class/osparc/product/quickStart/s4llite/Welcome.js +++ b/services/static-webserver/client/source/class/osparc/product/quickStart/s4llite/Welcome.js @@ -25,7 +25,7 @@ qx.Class.define("osparc.product.quickStart.s4llite.Welcome", { members: { _populateCard: function() { - const welcomeText = this.tr("Welcome onboard ") + osparc.utils.Utils.capitalize(osparc.auth.Data.getInstance().getFriendlyUsername()) + ","; + const welcomeText = this.tr("Welcome onboard ") + osparc.utils.Utils.capitalize(osparc.auth.Data.getInstance().getFriendlyUserName()) + ","; const welcome = osparc.product.quickStart.Utils.createLabel(welcomeText); this._add(welcome); diff --git a/services/static-webserver/client/source/class/osparc/product/quickStart/tis/Welcome.js b/services/static-webserver/client/source/class/osparc/product/quickStart/tis/Welcome.js index 25f3c6444aa1..afbff06ab41e 100644 --- a/services/static-webserver/client/source/class/osparc/product/quickStart/tis/Welcome.js +++ b/services/static-webserver/client/source/class/osparc/product/quickStart/tis/Welcome.js @@ -25,7 +25,7 @@ qx.Class.define("osparc.product.quickStart.tis.Welcome", { members: { _populateCard: function() { - const welcomeText = this.tr("Welcome onboard ") + osparc.utils.Utils.capitalize(osparc.auth.Data.getInstance().getFriendlyUsername()) + ","; + const welcomeText = this.tr("Welcome onboard ") + osparc.utils.Utils.capitalize(osparc.auth.Data.getInstance().getFriendlyUserName()) + ","; const welcome = osparc.product.quickStart.Utils.createLabel(welcomeText); this._add(welcome); diff --git a/services/static-webserver/client/source/class/osparc/share/NewCollaboratorsManager.js b/services/static-webserver/client/source/class/osparc/share/NewCollaboratorsManager.js index 71acad53e4c9..79ed43ca52f3 100644 --- a/services/static-webserver/client/source/class/osparc/share/NewCollaboratorsManager.js +++ b/services/static-webserver/client/source/class/osparc/share/NewCollaboratorsManager.js @@ -77,8 +77,8 @@ qx.Class.define("osparc.share.NewCollaboratorsManager", { switch (id) { case "intro-text": { let text = this.__showOrganizations ? - this.tr("Select organizations or users from the list or search by name, username or email.") : - this.tr("Select users from the list or search by name, username or email."); + this.tr("Select organizations or users from the list or search by name, userName or email.") : + this.tr("Select users from the list or search by name, userName or email."); text += "
" + this.tr("Keep in mind that users are only searchable based on the information they've chosen to make visible. To make yourself easier to find, adjust your visibility settings in My Account → Privacy."); control = new qx.ui.basic.Label().set({ value: text, diff --git a/services/static-webserver/client/source/class/osparc/share/RequestServiceAccess.js b/services/static-webserver/client/source/class/osparc/share/RequestServiceAccess.js index 9bd0269fa19f..c80121093d99 100644 --- a/services/static-webserver/client/source/class/osparc/share/RequestServiceAccess.js +++ b/services/static-webserver/client/source/class/osparc/share/RequestServiceAccess.js @@ -60,11 +60,11 @@ qx.Class.define("osparc.share.RequestServiceAccess", { cantReadServicesData.forEach((cantReadServiceData, idx) => { const userGroupId = cantReadServiceData["owner"]; if (userGroupId) { - const username = new qx.ui.basic.Label().set({ + const userName = new qx.ui.basic.Label().set({ rich: true, selectable: true, }); - layout.add(username, { + layout.add(userName, { row: idx+1, column: 0 }); @@ -88,11 +88,11 @@ qx.Class.define("osparc.share.RequestServiceAccess", { osparc.store.Users.getInstance().getUser(userGroupId) .then(user => { - username.setValue(user ? user.getLabel() : this.tr("Unknown user")); + userName.setValue(user ? user.getLabel() : this.tr("Unknown user")); email.setValue(user ? user.getEmail() : "Unknown email"); }) .catch(() => { - username.setValue(this.tr("Unknown user")); + userName.setValue(this.tr("Unknown user")); email.setValue("Unknown email"); }); } diff --git a/services/static-webserver/client/source/class/osparc/store/Groups.js b/services/static-webserver/client/source/class/osparc/store/Groups.js index 672d0befa9ac..b167643b80cb 100644 --- a/services/static-webserver/client/source/class/osparc/store/Groups.js +++ b/services/static-webserver/client/source/class/osparc/store/Groups.js @@ -108,9 +108,9 @@ qx.Class.define("osparc.store.Groups", { const myAuthData = osparc.auth.Data.getInstance(); const description = osparc.data.model.User.userDataToDescription(myAuthData.getFirstName(), myAuthData.getLastName(), myAuthData.getEmail()); groupMe.set({ - label: myAuthData.getUsername(), + label: myAuthData.getUserName(), description, - thumbnail: osparc.utils.Avatar.emailToThumbnail(myAuthData.getEmail(), myAuthData.getUsername()), + thumbnail: osparc.utils.Avatar.emailToThumbnail(myAuthData.getEmail(), myAuthData.getUserName()), }) return orgs; }); @@ -347,10 +347,10 @@ qx.Class.define("osparc.store.Groups", { return null; }, - getGroupMemberByUsername: function(orgId, username) { + getGroupMemberByUserName: function(orgId, userName) { const org = this.getGroup(orgId); if (org) { - return org.getGroupMemberByUsername(username); + return org.getGroupMemberByUserName(userName); } return null; }, @@ -424,7 +424,7 @@ qx.Class.define("osparc.store.Groups", { // CRUD GROUP // CRUD GROUP MEMBERS - addMember: function(orgId, username, email = null) { + addMember: function(orgId, userName, email = null) { const gid = parseInt(orgId); const params = { url: { @@ -435,7 +435,7 @@ qx.Class.define("osparc.store.Groups", { if (email) { params.data["email"] = email; } else { - params.data["userName"] = username; + params.data["userName"] = userName; } return osparc.data.Resources.fetch("organizationMembers", "post", params) .then(() => { @@ -444,7 +444,7 @@ qx.Class.define("osparc.store.Groups", { return this.__fetchGroupMembers(gid); }) .then(() => { - const groupMember = email ? this.getGroupMemberByLogin(gid, email) : this.getGroupMemberByUsername(gid, username); + const groupMember = email ? this.getGroupMemberByLogin(gid, email) : this.getGroupMemberByUserName(gid, userName); if (groupMember) { return groupMember; } diff --git a/services/static-webserver/client/source/class/osparc/support/SupportCenter.js b/services/static-webserver/client/source/class/osparc/support/SupportCenter.js index 2147c7de3c0c..1ee1ad1e6f44 100644 --- a/services/static-webserver/client/source/class/osparc/support/SupportCenter.js +++ b/services/static-webserver/client/source/class/osparc/support/SupportCenter.js @@ -43,12 +43,13 @@ qx.Class.define("osparc.support.SupportCenter", { statics: { WINDOW_WIDTH: 430, + WINDOW_HEIGHT: 700, REQUEST_CALL_MESSAGE: "Dear Support,\nI would like to make an appointment for a support call.", getMaxHeight: function() { - // height: max 80% of screen, or 600px + // height: max 80% of screen, or WINDOW_HEIGHTpx const clientHeight = document.documentElement.clientHeight; - return Math.min(600, parseInt(clientHeight * 0.8)); + return Math.min(osparc.support.SupportCenter.WINDOW_HEIGHT, parseInt(clientHeight * 0.8)); }, openWindow: function() { diff --git a/services/static-webserver/client/source/class/osparc/tester/WebSocketMessages.js b/services/static-webserver/client/source/class/osparc/tester/WebSocketMessages.js index 0872301459f0..dd07c2f4373d 100644 --- a/services/static-webserver/client/source/class/osparc/tester/WebSocketMessages.js +++ b/services/static-webserver/client/source/class/osparc/tester/WebSocketMessages.js @@ -78,7 +78,7 @@ qx.Class.define("osparc.tester.WebSocketMessages", { }); break; } - case "json-viewer": + case "json-tree-widget": control = new osparc.ui.basic.JsonTreeWidget(); this._add(control); break; @@ -89,7 +89,7 @@ qx.Class.define("osparc.tester.WebSocketMessages", { _buildLayout: function() { const filterMessage = this.getChildControl("filter-message"); const table = this.getChildControl("messages-table"); - const jsonViewer = this.getChildControl("json-viewer"); + const jsonTreeWidget = this.getChildControl("json-tree-widget"); const model = table.getTableModel(); filterMessage.addListener("changeValue", e => { @@ -101,7 +101,7 @@ qx.Class.define("osparc.tester.WebSocketMessages", { table.addListener("cellTap", e => { const selectedRow = e.getRow(); const rowData = table.getTableModel().getRowData(selectedRow); - jsonViewer.setJson(JSON.parse(rowData[2])); + jsonTreeWidget.setJson(JSON.parse(rowData[2])); }, this); this.__populateTable(); diff --git a/services/static-webserver/client/source/class/osparc/ui/basic/AvatarGroup.js b/services/static-webserver/client/source/class/osparc/ui/basic/AvatarGroup.js index dca045afbd89..85cfa1416abf 100644 --- a/services/static-webserver/client/source/class/osparc/ui/basic/AvatarGroup.js +++ b/services/static-webserver/client/source/class/osparc/ui/basic/AvatarGroup.js @@ -80,7 +80,7 @@ qx.Class.define("osparc.ui.basic.AvatarGroup", { .then(usersResult => { usersResult.forEach(user => { users.push({ - name: user.getUsername(), + name: user.getUserName(), avatar: user.getThumbnail(), }); }); diff --git a/services/static-webserver/client/source/class/osparc/ui/basic/JsonTreeWidget.js b/services/static-webserver/client/source/class/osparc/ui/basic/JsonTreeWidget.js index 60f5a55e5b16..179b632f22a9 100644 --- a/services/static-webserver/client/source/class/osparc/ui/basic/JsonTreeWidget.js +++ b/services/static-webserver/client/source/class/osparc/ui/basic/JsonTreeWidget.js @@ -48,7 +48,7 @@ qx.Class.define("osparc.ui.basic.JsonTreeWidget", { }, members: { - setJson(data) { + setJson: function(data) { const prettyJson = JSON.stringify(data, null, " ").replace(/\n/ig, "
"); this.setValue(prettyJson); } diff --git a/services/static-webserver/client/source/class/osparc/ui/basic/UserThumbnail.js b/services/static-webserver/client/source/class/osparc/ui/basic/UserThumbnail.js index 6b4de75cfacc..a9e0e4cb15aa 100644 --- a/services/static-webserver/client/source/class/osparc/ui/basic/UserThumbnail.js +++ b/services/static-webserver/client/source/class/osparc/ui/basic/UserThumbnail.js @@ -23,7 +23,7 @@ qx.Class.define("osparc.ui.basic.UserThumbnail", { this.set(osparc.utils.Utils.getThumbnailProps(size)); - if (osparc.data.Permissions.getInstance().isProductOwner()) { + if (osparc.store.Groups.getInstance().amIASupportUser()) { this.setCursor("pointer"); this.addListener("tap", this.__openUserDetails, this); } @@ -49,7 +49,7 @@ qx.Class.define("osparc.ui.basic.UserThumbnail", { __openUserDetails: function() { if (this.getUser()) { - const userDetails = new osparc.user.UserDetails(this.getUser()); + const userDetails = new osparc.user.UserDetails(this.getUser().getGroupId()); userDetails.center(); userDetails.open(); } diff --git a/services/static-webserver/client/source/class/osparc/user/UserDetails.js b/services/static-webserver/client/source/class/osparc/user/UserDetails.js index 90d42c21820c..fa1163cb9ff3 100644 --- a/services/static-webserver/client/source/class/osparc/user/UserDetails.js +++ b/services/static-webserver/client/source/class/osparc/user/UserDetails.js @@ -18,7 +18,7 @@ qx.Class.define("osparc.user.UserDetails", { extend: osparc.ui.window.Window, - construct: function(user) { + construct: function(userGroupId) { this.base(arguments); this.set({ @@ -27,25 +27,46 @@ qx.Class.define("osparc.user.UserDetails", { showMaximize: false, showMinimize: false, clickAwayClose: true, + contentPadding: 10, + width: this.self().WIDTH, + height: this.self().HEIGHT, }); - this.setUser(user); + this.setUserGroupId(userGroupId); }, statics: { - WIDTH: 300, - HEIGHT: 200, + WIDTH: 400, + HEIGHT: 600, + THUMBNAIL_SIZE: 110, - GRID_POS: { + TOP_GRID: { USERNAME: 0, FULLNAME: 1, EMAIL: 2, - USER_ID: 3, - GROUP_ID: 4, - } + PHONE: 3, + USER_ID: 4, + GROUP_ID: 5, + }, + + MIDDLE_GRID: { + INSTITUTION: 0, + ADDRESS: 1, + CITY: 2, + STATE: 3, + COUNTRY: 4, + POSTAL_CODE: 5, + }, }, properties: { + userGroupId: { + check: "Number", + init: null, + nullable: false, + apply: "__applyUserGroupId", + }, + user: { check: "osparc.data.model.User", init: null, @@ -56,23 +77,29 @@ qx.Class.define("osparc.user.UserDetails", { }, members: { + __remainingUserData: null, + _createChildControlImpl: function(id) { let control; switch (id) { case "top-layout": - control = new qx.ui.container.Composite(new qx.ui.layout.HBox(20)); + control = new qx.ui.container.Composite(new qx.ui.layout.HBox(30)); this.add(control); break; case "thumbnail": - control = new osparc.ui.basic.Thumbnail(null, 100, 100); + control = new osparc.ui.basic.Thumbnail(null, this.self().THUMBNAIL_SIZE, this.self().THUMBNAIL_SIZE).set({ + width: this.self().THUMBNAIL_SIZE, + height: this.self().THUMBNAIL_SIZE, + }); control.getChildControl("image").set({ anonymous: true, decorator: "rounded", }); this.getChildControl("top-layout").add(control); break; - case "main-info": { + case "top-info": { const grid = new qx.ui.layout.Grid(10, 6); + grid.setColumnWidth(0, 80); grid.setColumnFlex(1, 1); grid.setColumnAlign(0, "right", "middle"); control = new qx.ui.container.Composite(grid); @@ -81,84 +108,213 @@ qx.Class.define("osparc.user.UserDetails", { }); break; } - case "username": { - const title = new qx.ui.basic.Label("Username"); - this.getChildControl("main-info").add(title, { - row: this.self().GRID_POS.USERNAME, + case "middle-info": { + const grid = new qx.ui.layout.Grid(10, 6); + grid.setColumnWidth(0, 80); + grid.setColumnFlex(1, 1); + grid.setColumnAlign(0, "right", "middle"); + control = new qx.ui.container.Composite(grid); + this.add(control); + break; + } + case "userName": { + this.getChildControl("top-info").add(new qx.ui.basic.Label("UserName"), { + row: this.self().TOP_GRID.USERNAME, column: 0 }); control = new qx.ui.basic.Label(); - this.getChildControl("main-info").add(control, { - row: this.self().GRID_POS.USERNAME, + this.getChildControl("top-info").add(control, { + row: this.self().TOP_GRID.USERNAME, column: 1 }); break; } case "fullname": { - const title = new qx.ui.basic.Label("Full Name"); - this.getChildControl("main-info").add(title, { - row: this.self().GRID_POS.FULLNAME, + this.getChildControl("top-info").add(new qx.ui.basic.Label("Full Name"), { + row: this.self().TOP_GRID.FULLNAME, column: 0 }); control = new qx.ui.basic.Label(); - this.getChildControl("main-info").add(control, { - row: this.self().GRID_POS.FULLNAME, + this.getChildControl("top-info").add(control, { + row: this.self().TOP_GRID.FULLNAME, column: 1 }); break; } case "email": { - const title = new qx.ui.basic.Label("Email"); - this.getChildControl("main-info").add(title, { - row: this.self().GRID_POS.EMAIL, + this.getChildControl("top-info").add(new qx.ui.basic.Label("Email"), { + row: this.self().TOP_GRID.EMAIL, column: 0 }); control = new qx.ui.basic.Label(); - this.getChildControl("main-info").add(control, { - row: this.self().GRID_POS.EMAIL, + this.getChildControl("top-info").add(control, { + row: this.self().TOP_GRID.EMAIL, + column: 1 + }); + break; + } + case "phone": { + this.getChildControl("top-info").add(new qx.ui.basic.Label("Phone"), { + row: this.self().TOP_GRID.PHONE, + column: 0 + }); + control = new qx.ui.basic.Label(); + this.getChildControl("top-info").add(control, { + row: this.self().TOP_GRID.PHONE, column: 1 }); break; } case "user-id": { - const title = new qx.ui.basic.Label("User ID"); - this.getChildControl("main-info").add(title, { - row: this.self().GRID_POS.USER_ID, + this.getChildControl("top-info").add(new qx.ui.basic.Label("User ID"), { + row: this.self().TOP_GRID.USER_ID, column: 0 }); control = new qx.ui.basic.Label(); - this.getChildControl("main-info").add(control, { - row: this.self().GRID_POS.USER_ID, + this.getChildControl("top-info").add(control, { + row: this.self().TOP_GRID.USER_ID, column: 1 }); break; } case "group-id": { - const title = new qx.ui.basic.Label("Group ID"); - this.getChildControl("main-info").add(title, { - row: this.self().GRID_POS.GROUP_ID, + this.getChildControl("top-info").add(new qx.ui.basic.Label("Group ID"), { + row: this.self().TOP_GRID.GROUP_ID, column: 0 }); control = new qx.ui.basic.Label(); - this.getChildControl("main-info").add(control, { - row: this.self().GRID_POS.GROUP_ID, + this.getChildControl("top-info").add(control, { + row: this.self().TOP_GRID.GROUP_ID, column: 1 }); break; } + case "institution": + this.getChildControl("middle-info").add(new qx.ui.basic.Label("Institution"), { + row: this.self().MIDDLE_GRID.INSTITUTION, + column: 0 + }); + control = new qx.ui.basic.Label(); + this.getChildControl("middle-info").add(control, { + row: this.self().MIDDLE_GRID.INSTITUTION, + column: 1 + }); + break; + case "address": + this.getChildControl("middle-info").add(new qx.ui.basic.Label("Address"), { + row: this.self().MIDDLE_GRID.ADDRESS, + column: 0 + }); + control = new qx.ui.basic.Label(); + this.getChildControl("middle-info").add(control, { + row: this.self().MIDDLE_GRID.ADDRESS, + column: 1 + }); + break; + case "city": + this.getChildControl("middle-info").add(new qx.ui.basic.Label("City"), { + row: this.self().MIDDLE_GRID.CITY, + column: 0 + }); + control = new qx.ui.basic.Label(); + this.getChildControl("middle-info").add(control, { + row: this.self().MIDDLE_GRID.CITY, + column: 1 + }); + break; + case "state": + this.getChildControl("middle-info").add(new qx.ui.basic.Label("State"), { + row: this.self().MIDDLE_GRID.STATE, + column: 0 + }); + control = new qx.ui.basic.Label(); + this.getChildControl("middle-info").add(control, { + row: this.self().MIDDLE_GRID.STATE, + column: 1 + }); + break; + case "country": + this.getChildControl("middle-info").add(new qx.ui.basic.Label("Country"), { + row: this.self().MIDDLE_GRID.COUNTRY, + column: 0 + }); + control = new qx.ui.basic.Label(); + this.getChildControl("middle-info").add(control, { + row: this.self().MIDDLE_GRID.COUNTRY, + column: 1 + }); + break; + case "postal-code": + this.getChildControl("middle-info").add(new qx.ui.basic.Label("Postal Code"), { + row: this.self().MIDDLE_GRID.POSTAL_CODE, + column: 0 + }); + control = new qx.ui.basic.Label(); + this.getChildControl("middle-info").add(control, { + row: this.self().MIDDLE_GRID.POSTAL_CODE, + column: 1 + }); + break; } return control || this.base(arguments, id); }, + __applyUserGroupId: function(userGroupId) { + const params = { + url: { + gId: userGroupId + } + }; + osparc.data.Resources.fetch("poUsers", "searchByGroupId", params) + .then(usersData => { + if (usersData.length === 1) { + const userData = usersData[0]; + // curate data + userData["groupId"] = userGroupId; + userData["userId"] = -1; // fix this + userData["userName"] = "userName"; // fix this + const user = new osparc.data.model.User(userData); + user.setContactData(userData); + // remove the displayed properties from the contact info + Object.keys(qx.util.PropertyUtil.getProperties(osparc.data.model.User)).forEach(prop => delete userData[prop]); + this.__remainingUserData = osparc.utils.Utils.convertKeysToTitles(userData); + this.setUser(user); + } + }) + .catch(err => { + console.error(err); + this.close(); + }); + }, + __applyUser: function(user) { - this.setCaption(user.getUsername()); + this.setCaption(user.getUserName()); - this.getChildControl("thumbnail").setSource(user.createThumbnail(96)); - this.getChildControl("username").setValue(user.getUsername()); + // top grid + this.getChildControl("userName").setValue(user.getUserName()); this.getChildControl("fullname").setValue([user.getFirstName(), user.getLastName()].filter(Boolean).join(" ")); this.getChildControl("email").setValue(user.getEmail()); + this.getChildControl("phone").setValue(user.getPhone() || "-"); this.getChildControl("user-id").setValue(String(user.getUserId())); this.getChildControl("group-id").setValue(String(user.getGroupId())); + + this.getChildControl("thumbnail").setSource(user.createThumbnail(this.self().THUMBNAIL_SIZE)); + + // middle grid + this.getChildControl("institution").setValue(user.getInstitution() || "-"); + this.getChildControl("address").setValue(user.getAddress() || "-"); + this.getChildControl("city").setValue(user.getCity() || "-"); + this.getChildControl("state").setValue(user.getState() || "-"); + this.getChildControl("country").setValue(user.getCountry() || "-"); + this.getChildControl("postal-code").setValue(user.getPostalCode() || "-"); + + // remaining data + const jsonViewer = new osparc.widget.JsonFormatterWidget(this.__remainingUserData); + const scroll = new qx.ui.container.Scroll(); + scroll.add(jsonViewer); + this.add(scroll, { + flex: 1 + }); }, } }); diff --git a/services/static-webserver/client/source/class/osparc/utils/Avatar.js b/services/static-webserver/client/source/class/osparc/utils/Avatar.js index a43544718ebe..6149f217d952 100644 --- a/services/static-webserver/client/source/class/osparc/utils/Avatar.js +++ b/services/static-webserver/client/source/class/osparc/utils/Avatar.js @@ -34,7 +34,7 @@ qx.Class.define("osparc.utils.Avatar", { type: "static", statics: { - emailToThumbnail: function(email, username = "??", size = 32) { + emailToThumbnail: function(email, userName = "??", size = 32) { email = email || ""; // MD5 (Message-Digest Algorithm) by WebToolkit const MD5 = function(s) { @@ -255,7 +255,7 @@ qx.Class.define("osparc.utils.Avatar", { }; const emailHash = MD5(email); - const defaultImageUrl = `https://ui-avatars.com/api/${username}/${size}`; + const defaultImageUrl = `https://ui-avatars.com/api/${userName}/${size}`; return `https://www.gravatar.com/avatar/${emailHash}?d=${defaultImageUrl}&s=${size}&r=g`; }, } diff --git a/services/static-webserver/client/source/class/osparc/utils/Utils.js b/services/static-webserver/client/source/class/osparc/utils/Utils.js index c7e93416d908..5d60bb63c84a 100644 --- a/services/static-webserver/client/source/class/osparc/utils/Utils.js +++ b/services/static-webserver/client/source/class/osparc/utils/Utils.js @@ -1197,6 +1197,18 @@ qx.Class.define("osparc.utils.Utils", { return str; }, + camelToTitle: function(str) { + return str + .replace(/([A-Z])/g, ' $1') // insert space before capital letters + .replace(/^./, c => c.toUpperCase()); // capitalize first letter + }, + + convertKeysToTitles: function(obj) { + return Object.fromEntries( + Object.entries(obj).map(([key, value]) => [this.camelToTitle(key), value]) + ); + }, + setIdToWidget: (qWidget, id) => { if (qWidget.getContentElement && qWidget.getContentElement() && id) { qWidget.getContentElement().setAttribute("osparc-test-id", id); diff --git a/services/static-webserver/client/source/class/osparc/widget/JsonFormatterWidget.js b/services/static-webserver/client/source/class/osparc/widget/JsonFormatterWidget.js new file mode 100644 index 000000000000..852c66c96cf3 --- /dev/null +++ b/services/static-webserver/client/source/class/osparc/widget/JsonFormatterWidget.js @@ -0,0 +1,109 @@ +/* ************************************************************************ + + osparc - the simcore frontend + + https://osparc.io + + Copyright: + 2025 IT'IS Foundation, https://itis.swiss + + License: + MIT: https://opensource.org/licenses/MIT + + Authors: + * Odei Maiz (odeimaiz) + +************************************************************************ */ + + +qx.Class.define("osparc.widget.JsonFormatterWidget", { + extend: qx.ui.core.Widget, + + construct: function(json) { + this.base(arguments); + + this._setLayout(new qx.ui.layout.Grow()); + + this.set({ + allowGrowX: true, + allowGrowY: true, + width: null, + height: null + }); + + if (json) { + this.setJson(json); + } + }, + + members: { + __formatterEl: null, + __root: null, + + _createContentElement: function() { + this.__root = new qx.html.Element("div"); + this.__root.addClass("osparc-json-formatter-root"); + this.__root.setStyles({ + width: "100%", + height: "100%", + boxSizing: "border-box", + overflow: "auto" // ensure local overflow is visible + }); + return this.__root; + }, + + _getContentHint: function() { + if (this.__formatterEl) { + return { + width: this.__formatterEl.scrollWidth, + height: this.__formatterEl.scrollHeight + }; + } + return { width: 100, height: 50 }; + }, + + setJson: function(json) { + if (!this.getContentElement().getDomElement()) { + this.addListenerOnce("appear", () => this._mountJson(json), this); + } else { + this._mountJson(json); + } + }, + + _mountJson: function(json) { + if (this.__formatterEl && this.__formatterEl.parentNode) { + this.__formatterEl.parentNode.removeChild(this.__formatterEl); + this.__formatterEl = null; + } + + let jsonObj = json; + if (typeof json === "string") { + try { + jsonObj = JSON.parse(json); + } catch (e) { + console.warn("setJson(): invalid JSON string, rendering raw", e); + } + } + + if (typeof JSONFormatter === "undefined") { + console.error("JSONFormatter is not available"); + return; + } + + const formatter = new JSONFormatter(jsonObj, 2, {}); + this.__formatterEl = formatter.render(); + + const rootDom = this.getContentElement().getDomElement(); + if (rootDom) { + rootDom.appendChild(this.__formatterEl); + } + this.invalidateLayoutCache(); // notify qooxdoo to recalc size + }, + }, + + destruct: function() { + if (this.__formatterEl && this.__formatterEl.parentNode) { + this.__formatterEl.parentNode.removeChild(this.__formatterEl); + } + } +}); diff --git a/services/static-webserver/client/source/class/osparc/wrapper/JsonFormatter.js b/services/static-webserver/client/source/class/osparc/wrapper/JsonFormatter.js index 77c219f5452e..8ba12d65188c 100644 --- a/services/static-webserver/client/source/class/osparc/wrapper/JsonFormatter.js +++ b/services/static-webserver/client/source/class/osparc/wrapper/JsonFormatter.js @@ -63,8 +63,15 @@ qx.Class.define("osparc.wrapper.JsonFormatter", { ]); dynLoader.addListenerOnce("ready", () => { + if (typeof JSONFormatter === "undefined") { + reject(new Error("JSONFormatter loaded but did not export to window.JSONFormatter")); + return; + } console.log(jsonFormatterPath + " loaded"); this.setLibReady(true); + + this.__applyStyles(); + resolve(); }, this); @@ -78,6 +85,26 @@ qx.Class.define("osparc.wrapper.JsonFormatter", { }); }, + __applyStyles: function() { + const styleId = "json-formatter-osparc-style"; + if (!document.getElementById(styleId)) { + const color = qx.theme.manager.Color.getInstance().resolve("text"); + const style = document.createElement("style"); + style.id = styleId; + style.innerHTML = ` + .osparc-json-formatter-root * { + color: ${color} !important; /* Use osparc text color */ + font-family: "Manrope", sans-serif !important; /* Use osparc font */ + font-size: 13px !important; /* Force all fonts to 13px */ + } + .osparc-json-formatter-root .json-formatter-constructor-name { + display: none !important; /* Hide "Object" and "Array(n)" labels */ + } + `; + document.head.appendChild(style); + } + }, + createContainer: function(divId) { const container = new qx.ui.embed.Html("
");