Skip to content

🎨 [Frontend] Feature: Hide username #7406

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 56 commits into from
Mar 24, 2025
Merged
Show file tree
Hide file tree
Changes from 20 commits
Commits
Show all changes
56 commits
Select commit Hold shift + click to select a range
ce0a606
drafts test
pcrespov Mar 20, 2025
d5f2e7e
privacy
pcrespov Mar 20, 2025
47d8bc5
migration
pcrespov Mar 20, 2025
c7b2357
update OAS
pcrespov Mar 20, 2025
badef8f
services/webserver api version: 0.61.2 → 0.61.3
pcrespov Mar 20, 2025
8e89260
fixes tests
pcrespov Mar 20, 2025
afe375c
cleanuppre
pcrespov Mar 20, 2025
c672b55
fixes test
pcrespov Mar 20, 2025
e72b5d5
fixes test
pcrespov Mar 20, 2025
d2fbd04
helpers
pcrespov Mar 20, 2025
ef5f72a
self test
pcrespov Mar 20, 2025
8eb1612
fixes test
pcrespov Mar 20, 2025
ae47f89
Merge branch 'master' into is38/username-privacy
pcrespov Mar 21, 2025
3431e8d
hideUsername field and message
odeimaiz Mar 21, 2025
f665a5c
Merge branch 'master' into feature/hide-username
odeimaiz Mar 21, 2025
2057d34
optOutMessage
odeimaiz Mar 21, 2025
9cd1a0c
optOutMessage
odeimaiz Mar 21, 2025
43c5e89
eyes next to the fields
odeimaiz Mar 21, 2025
12264dd
dynamic eyes
odeimaiz Mar 21, 2025
b048916
minor
odeimaiz Mar 21, 2025
27c13c8
username is nullable
odeimaiz Mar 21, 2025
c11d3a0
minor
odeimaiz Mar 21, 2025
f138b4c
missing fields
pcrespov Mar 21, 2025
3a30f39
constant
pcrespov Mar 21, 2025
4aa012a
refactor
pcrespov Mar 21, 2025
86422c2
test
pcrespov Mar 21, 2025
38400c1
retire put
pcrespov Mar 21, 2025
8ea9dfd
update OAS
pcrespov Mar 21, 2025
4c3f5be
services/webserver api version: 0.61.3 → 0.61.4
pcrespov Mar 21, 2025
e37dc5f
wrong import
pcrespov Mar 21, 2025
a0c3bb2
wrong example
pcrespov Mar 21, 2025
f07de3f
fixes test
pcrespov Mar 21, 2025
12d0665
Merge branch 'master' into feature/hide-username
odeimaiz Mar 24, 2025
f16bd1d
Merge branch 'is38/missing-username-privacy' of github.com:pcrespov/o…
odeimaiz Mar 24, 2025
e9735c4
minor
odeimaiz Mar 24, 2025
6fca955
more startup calls
odeimaiz Mar 24, 2025
03a15c3
missing fields
pcrespov Mar 21, 2025
b67d799
constant
pcrespov Mar 21, 2025
3c17c2b
refactor
pcrespov Mar 21, 2025
fd4dad6
test
pcrespov Mar 21, 2025
a205478
retire put
pcrespov Mar 21, 2025
00eaff1
update OAS
pcrespov Mar 21, 2025
5e0789f
services/webserver api version: 0.61.3 → 0.61.4
pcrespov Mar 21, 2025
06e7f4c
wrong import
pcrespov Mar 21, 2025
eaa357e
wrong example
pcrespov Mar 21, 2025
3de5949
fixes test
pcrespov Mar 21, 2025
ea59980
@odeimaiz review: missing field
pcrespov Mar 24, 2025
1e0eaff
better practices
odeimaiz Mar 24, 2025
d63516b
minor
odeimaiz Mar 24, 2025
f0f4e0f
enable button
odeimaiz Mar 24, 2025
f5107dc
profileFields
odeimaiz Mar 24, 2025
4866179
Merge branch 'is38/missing-username-privacy' of github.com:pcrespov/o…
odeimaiz Mar 24, 2025
6ea4ba7
minor
odeimaiz Mar 24, 2025
66e3490
do not check tasks
odeimaiz Mar 24, 2025
fd65ac4
Merge branch 'master' into feature/hide-username
odeimaiz Mar 24, 2025
10f741d
bad merge
odeimaiz Mar 24, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ qx.Class.define("osparc.desktop.account.ProfilePage", {
members: {
__userProfileData: null,
__userProfileModel: null,
__userProfileRenderer: null,
__userPrivacyData: null,
__userPrivacyModel: null,
__userProfileForm: null,
Expand Down Expand Up @@ -75,9 +76,20 @@ qx.Class.define("osparc.desktop.account.ProfilePage", {
if (privacyData) {
this.__userPrivacyData = privacyData;
this.__userPrivacyModel.set({
"hideUsername": "hideUsername" in privacyData ? privacyData["hideUsername"] : false,
"hideFullname": "hideFullname" in privacyData ? privacyData["hideFullname"] : true,
"hideEmail": "hideEmail" in privacyData ? privacyData["hideEmail"] : true,
});

const visibleIcon = "@FontAwesome5Solid/eye/12";
const hiddenIcon = "@FontAwesome5Solid/eye-slash/12";
const icons = {
0: this.__userPrivacyModel.getHideUsername() ? hiddenIcon : visibleIcon,
1: this.__userPrivacyModel.getHideFullname() ? hiddenIcon : visibleIcon,
2: this.__userPrivacyModel.getHideFullname() ? hiddenIcon : visibleIcon,
3: this.__userPrivacyModel.getHideEmail() ? hiddenIcon : visibleIcon,
};
this.__userProfileRenderer.setIcons(icons);
}
},

Expand Down Expand Up @@ -110,7 +122,8 @@ qx.Class.define("osparc.desktop.account.ProfilePage", {
form.add(firstName, "First Name", null, "firstName");
form.add(lastName, "Last Name", null, "lastName");
form.add(email, "Email", null, "email");
box.add(new qx.ui.form.renderer.Single(form));
const singleWithIcon = this.__userProfileRenderer = new osparc.ui.form.renderer.SingleWithIcon(form);
box.add(singleWithIcon);

const expirationLayout = new qx.ui.container.Composite(new qx.ui.layout.HBox(5)).set({
paddingLeft: 16,
Expand Down Expand Up @@ -215,15 +228,27 @@ qx.Class.define("osparc.desktop.account.ProfilePage", {
},

__createPrivacySection: function() {
// binding to a model
const raw = {
"hideUsername": false,
"hideFullname": true,
"hideEmail": true,
};

const privacyModel = this.__userPrivacyModel = qx.data.marshal.Json.createModel(raw);

const box = osparc.ui.window.TabbedView.createSectionBox(this.tr("Privacy"));
box.set({
alignX: "left",
maxWidth: 500
});

const label = osparc.ui.window.TabbedView.createHelpLabel(this.tr("For Privacy reasons, you might want to hide your First and Last Names and/or the Email to other users"));
const label = osparc.ui.window.TabbedView.createHelpLabel(this.tr("For Privacy reasons, you might want to hide some personal data."));
box.add(label);

const hideUsername = new qx.ui.form.CheckBox().set({
value: false
});
const hideFullname = new qx.ui.form.CheckBox().set({
value: true
});
Expand All @@ -232,18 +257,13 @@ qx.Class.define("osparc.desktop.account.ProfilePage", {
});

const form = new qx.ui.form.Form();
form.add(hideUsername, "Hide Username", null, "hideUsername");
form.add(hideFullname, "Hide Full Name", null, "hideFullname");
form.add(hideEmail, "Hide Email", null, "hideEmail");
box.add(new qx.ui.form.renderer.Single(form));

// binding to a model
const raw = {
"hideFullname": true,
"hideEmail": true,
};

const model = this.__userPrivacyModel = qx.data.marshal.Json.createModel(raw);
const controller = new qx.data.controller.Object(model);
const controller = new qx.data.controller.Object(privacyModel);
controller.addTarget(hideUsername, "value", "hideUsername", true);
controller.addTarget(hideFullname, "value", "hideFullname", true);
controller.addTarget(hideEmail, "value", "hideEmail", true);

Expand All @@ -261,11 +281,14 @@ qx.Class.define("osparc.desktop.account.ProfilePage", {
const patchData = {
"privacy": {}
};
if (this.__userPrivacyData["hideFullname"] !== model.getHideFullname()) {
patchData["privacy"]["hideFullname"] = model.getHideFullname();
if (this.__userPrivacyData["hideUsername"] !== privacyModel.getHideUsername()) {
patchData["privacy"]["hideUsername"] = privacyModel.getHideUsername();
}
if (this.__userPrivacyData["hideEmail"] !== model.getHideEmail()) {
patchData["privacy"]["hideEmail"] = model.getHideEmail();
if (this.__userPrivacyData["hideFullname"] !== privacyModel.getHideFullname()) {
patchData["privacy"]["hideFullname"] = privacyModel.getHideFullname();
}
if (this.__userPrivacyData["hideEmail"] !== privacyModel.getHideEmail()) {
patchData["privacy"]["hideEmail"] = privacyModel.getHideEmail();
}

if (
Expand Down Expand Up @@ -298,6 +321,29 @@ qx.Class.define("osparc.desktop.account.ProfilePage", {
}
});

const optOutMessage = new qx.ui.basic.Atom().set({
label: this.tr("If all searchable fields are hidden, you will not be findable."),
icon: "@FontAwesome5Solid/exclamation-triangle/14",
gap: 8,
allowGrowX: false,
});
optOutMessage.getChildControl("icon").setTextColor("warning-yellow")
box.add(optOutMessage);
const privacyFields = [
hideUsername,
hideFullname,
hideEmail,
]
const evaluateWarningMessage = () => {
if (privacyFields.every(privacyField => privacyField.getValue())) {
optOutMessage.show();
} else {
optOutMessage.exclude();
}
};
evaluateWarningMessage();
privacyFields.forEach(privacyField => privacyField.addListener("changeValue", () => evaluateWarningMessage()));

return box;
},

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
/* ************************************************************************

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.ui.form.renderer.SingleWithIcon", {
extend: qx.ui.form.renderer.Single,

construct: function(form, icons) {
if (icons) {
this.__icons = icons;
} else {
this.__icons = {};
}

this.base(arguments, form);
},

members: {
__icons: null,

setIcons: function(icons) {
this.__icons = icons;

this._onFormChange();
},

// overridden
addItems: function(items, names, title, itemOptions, headerOptions) {
this.base(arguments, items, names, title, itemOptions, headerOptions);

// header
let row = title === null ? 0 : 1;

for (let i = 0; i < items.length; i++) {
if (i in this.__icons) {
const image = new qx.ui.basic.Image(this.__icons[i]).set({
alignY: "middle",
});
this._add(image, {
row,
column: 2,
});
}

row++;
}
},
}
});
Loading