Skip to content

Commit 7f0830f

Browse files
authored
🎨 [Frontend] Distinguish product groups (Everyone/Public and Support) (#8335)
1 parent 2e2b2a9 commit 7f0830f

File tree

10 files changed

+119
-15
lines changed

10 files changed

+119
-15
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ qx.Class.define("osparc.dashboard.CardBase", {
5252
statics: {
5353
SHARE_ICON: "@FontAwesome5Solid/share-alt/13",
5454
SHARED_USER: "@FontAwesome5Solid/user/13",
55-
SHARED_SUPPORT: "@FontAwesome5Solid/question/13",
55+
SHARED_SUPPORT: "@FontAwesome5Solid/question-circle/13",
5656
SHARED_ORGS: "@FontAwesome5Solid/users/13",
5757
SHARED_ALL: "@FontAwesome5Solid/globe/13",
5858
PERM_READ: "@FontAwesome5Solid/eye/13",

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1660,6 +1660,8 @@ qx.Class.define("osparc.data.Resources", {
16601660
status = errorData.status;
16611661
if (errorData["support_id"]) {
16621662
supportId = errorData["support_id"];
1663+
} else if (errorData["supportId"]) {
1664+
supportId = errorData["supportId"];
16631665
}
16641666
} else {
16651667
const req = e.getRequest();

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ qx.Class.define("osparc.data.model.Group", {
9696
statics: {
9797
getProperties: function() {
9898
return Object.keys(qx.util.PropertyUtil.getProperties(osparc.data.model.Group));
99-
}
99+
},
100100
},
101101

102102
members: {

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

Lines changed: 41 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,11 @@ qx.Class.define("osparc.desktop.organizations.OrganizationsList", {
6969

7070
statics: {
7171
sortOrganizations: function(a, b) {
72+
const collabTypeOrder = osparc.store.Groups.COLLAB_TYPE_ORDER;
73+
const typeDiff = collabTypeOrder.indexOf(a.getGroupType()) - collabTypeOrder.indexOf(b.getGroupType());
74+
if (typeDiff !== 0) {
75+
return typeDiff;
76+
}
7277
const sorted = osparc.share.Collaborators.sortByAccessRights(a.getAccessRights(), b.getAccessRights());
7378
if (sorted !== 0) {
7479
return sorted;
@@ -84,7 +89,7 @@ qx.Class.define("osparc.desktop.organizations.OrganizationsList", {
8489
getOrgModel: function(orgId) {
8590
let org = null;
8691
this.__orgsModel.forEach(orgModel => {
87-
if (orgModel.getGroupId() === parseInt(orgId)) {
92+
if ("getGroupId" in orgModel && orgModel.getGroupId() === parseInt(orgId)) {
8893
org = orgModel;
8994
}
9095
});
@@ -141,6 +146,10 @@ qx.Class.define("osparc.desktop.organizations.OrganizationsList", {
141146
ctrl.bindProperty("description", "subtitle", null, item, id);
142147
ctrl.bindProperty("groupMembers", "groupMembers", null, item, id);
143148
ctrl.bindProperty("accessRights", "accessRights", null, item, id);
149+
// handle separator
150+
ctrl.bindProperty("isSeparator", "enabled", {
151+
converter: val => !val // disable clicks on separator
152+
}, item, id);
144153
},
145154
configureItem: item => {
146155
item.subscribeToFilterGroup("organizationsList");
@@ -160,6 +169,15 @@ qx.Class.define("osparc.desktop.organizations.OrganizationsList", {
160169
const orgKey = e.getData();
161170
this.__deleteOrganization(orgKey);
162171
});
172+
item.addListener("changeEnabled", e => {
173+
if (!e.getData()) {
174+
item.set({
175+
minHeight: 1,
176+
maxHeight: 1,
177+
decorator: "separator-strong",
178+
});
179+
}
180+
});
163181
}
164182
});
165183

@@ -184,7 +202,28 @@ qx.Class.define("osparc.desktop.organizations.OrganizationsList", {
184202
const groupsStore = osparc.store.Groups.getInstance();
185203
const orgs = Object.values(groupsStore.getOrganizations());
186204
orgs.sort(this.self().sortOrganizations);
187-
orgs.forEach(org => orgsModel.append(org));
205+
206+
// insert a separator between product and non-product groups
207+
const productGroup = [
208+
osparc.store.Groups.COLLAB_TYPE.EVERYONE,
209+
osparc.store.Groups.COLLAB_TYPE.SUPPORT,
210+
];
211+
const hasProductGroup = orgs.some(org => productGroup.includes(org.getGroupType()));
212+
const hasNonProductGroup = orgs.some(org => !productGroup.includes(org.getGroupType()));
213+
let separatorInserted = false;
214+
orgs.forEach(org => {
215+
const isProductGroup = productGroup.includes(org.getGroupType());
216+
// Only insert separator if both sides exist
217+
if (!isProductGroup && hasProductGroup && hasNonProductGroup && !separatorInserted) {
218+
const separator = {
219+
isSeparator: true
220+
};
221+
orgsModel.append(qx.data.marshal.Json.createModel(separator));
222+
separatorInserted = true;
223+
}
224+
orgsModel.append(org);
225+
});
226+
188227
this.setOrganizationsLoaded(true);
189228
if (orgId) {
190229
this.fireDataEvent("organizationSelected", orgId);

services/static-webserver/client/source/class/osparc/filter/CollaboratorToggleButton.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,10 @@ qx.Class.define("osparc.filter.CollaboratorToggleButton", {
5656
}
5757
}
5858
this.setIcon(iconPath);
59+
this.getChildControl("icon").set({
60+
width: 17, // align with widest icon: "users"
61+
scale: true,
62+
});
5963
this.setLabel(label);
6064
if (toolTipText) {
6165
const infoButton = new osparc.ui.hint.InfoHint(toolTipText);

services/static-webserver/client/source/class/osparc/filter/OrganizationsAndMembers.js

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -64,13 +64,7 @@ qx.Class.define("osparc.filter.OrganizationsAndMembers", {
6464

6565
const visibleCollaborators = Object.values(this.__visibleCollaborators);
6666

67-
// define the priority order
68-
const collabTypeOrder = [
69-
osparc.store.Groups.COLLAB_TYPE.EVERYONE,
70-
osparc.store.Groups.COLLAB_TYPE.SUPPORT,
71-
osparc.store.Groups.COLLAB_TYPE.ORGANIZATION,
72-
osparc.store.Groups.COLLAB_TYPE.USER
73-
];
67+
const collabTypeOrder = osparc.store.Groups.COLLAB_TYPE_ORDER;
7468
// sort them first
7569
visibleCollaborators.sort((a, b) => {
7670
const typeDiff = collabTypeOrder.indexOf(a["collabType"]) - collabTypeOrder.indexOf(b["collabType"]);

services/static-webserver/client/source/class/osparc/share/Collaborators.js

Lines changed: 54 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,15 @@ qx.Class.define("osparc.share.Collaborators", {
4343
},
4444

4545
statics: {
46+
sortProductGroupsFirst: function(a, b) {
47+
const collabTypeOrder = osparc.store.Groups.COLLAB_TYPE_ORDER;
48+
const indexA = collabTypeOrder.indexOf(a["collabType"]);
49+
const indexB = collabTypeOrder.indexOf(b["collabType"]);
50+
const posA = indexA === -1 ? Number.MAX_SAFE_INTEGER : indexA;
51+
const posB = indexB === -1 ? Number.MAX_SAFE_INTEGER : indexB;
52+
return posA - posB;
53+
},
54+
4655
sortByAccessRights: function(aAccessRights, bAccessRights) {
4756
if (aAccessRights["delete"] !== bAccessRights["delete"]) {
4857
return bAccessRights["delete"] - aAccessRights["delete"];
@@ -57,9 +66,16 @@ qx.Class.define("osparc.share.Collaborators", {
5766
},
5867

5968
sortStudyOrServiceCollabs: function(a, b) {
69+
// product related groups first
70+
let sorted = null;
71+
sorted = this.self().sortProductGroupsFirst(a, b);
72+
if (sorted !== 0) {
73+
return sorted;
74+
}
75+
76+
// then by access rights
6077
const aAccessRights = a["accessRights"];
6178
const bAccessRights = b["accessRights"];
62-
let sorted = null;
6379
if ("delete" in aAccessRights) {
6480
// studies
6581
sorted = this.self().sortByAccessRights(aAccessRights, bAccessRights);
@@ -334,6 +350,10 @@ qx.Class.define("osparc.share.Collaborators", {
334350
ctrl.bindProperty("resourceType", "resourceType", null, item, id); // Resource type
335351
ctrl.bindProperty("accessRights", "accessRights", null, item, id);
336352
ctrl.bindProperty("showOptions", "showOptions", null, item, id);
353+
// handle separator
354+
ctrl.bindProperty("isSeparator", "enabled", {
355+
converter: val => !val // disable clicks on separator
356+
}, item, id);
337357
},
338358
configureItem: item => {
339359
item.getChildControl("thumbnail").getContentElement()
@@ -380,6 +400,15 @@ qx.Class.define("osparc.share.Collaborators", {
380400
}
381401
this._deleteMember(orgMember, item);
382402
});
403+
item.addListener("changeEnabled", e => {
404+
if (!e.getData()) {
405+
item.set({
406+
minHeight: 1,
407+
maxHeight: 1,
408+
decorator: "separator-strong",
409+
});
410+
}
411+
});
383412
}
384413
});
385414
vBox.add(collaboratorsUIList, {
@@ -462,8 +491,10 @@ qx.Class.define("osparc.share.Collaborators", {
462491
// organization
463492
if (everyoneGroupIds.includes(parseInt(gid))) {
464493
collaborator["thumbnail"] = "@FontAwesome5Solid/globe/32";
494+
collaborator["collabType"] = osparc.store.Groups.COLLAB_TYPE.EVERYONE; // needed for sorting per product related groups
465495
} else if (supportGroup && supportGroup.getGroupId() === parseInt(gid)) {
466-
collaborator["thumbnail"] = supportGroup.getThumbnail();
496+
collaborator["thumbnail"] = "@FontAwesome5Solid/question-circle/32";
497+
collaborator["collabType"] = osparc.store.Groups.COLLAB_TYPE.SUPPORT; // needed for sorting per product related groups
467498
} else if (!collaborator["thumbnail"]) {
468499
collaborator["thumbnail"] = "@FontAwesome5Solid/users/26";
469500
}
@@ -475,7 +506,27 @@ qx.Class.define("osparc.share.Collaborators", {
475506
}
476507
}
477508
collaboratorsList.sort(this.self().sortStudyOrServiceCollabs);
478-
collaboratorsList.forEach(c => this.__collaboratorsModel.append(qx.data.marshal.Json.createModel(c)));
509+
510+
// insert a separator between product and non-product groups
511+
const productGroup = [
512+
osparc.store.Groups.COLLAB_TYPE.EVERYONE,
513+
osparc.store.Groups.COLLAB_TYPE.SUPPORT,
514+
];
515+
const hasProductGroup = collaboratorsList.some(c => productGroup.includes(c.collabType));
516+
const hasNonProductGroup = collaboratorsList.some(c => !productGroup.includes(c.collabType));
517+
let separatorInserted = false;
518+
collaboratorsList.forEach(c => {
519+
const isProductGroup = productGroup.includes(c.collabType);
520+
// Only insert separator if both sides exist
521+
if (!isProductGroup && hasProductGroup && hasNonProductGroup && !separatorInserted) {
522+
const separator = {
523+
isSeparator: true
524+
};
525+
this.__collaboratorsModel.append(qx.data.marshal.Json.createModel(separator));
526+
separatorInserted = true;
527+
}
528+
this.__collaboratorsModel.append(qx.data.marshal.Json.createModel(c));
529+
});
479530
},
480531

481532
_addEditors: function(gids) {

services/static-webserver/client/source/class/osparc/store/Groups.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,13 @@ qx.Class.define("osparc.store.Groups", {
6262
ORGANIZATION: "organization",
6363
USER: "user",
6464
},
65+
66+
COLLAB_TYPE_ORDER: [
67+
"everyone", // osparc.store.Groups.COLLAB_TYPE.EVERYONE
68+
"support", // osparc.store.Groups.COLLAB_TYPE.SUPPORT,
69+
"organization", // osparc.store.Groups.COLLAB_TYPE.ORGANIZATION
70+
"user", // osparc.store.Groups.COLLAB_TYPE.USER
71+
],
6572
},
6673

6774
members: {

services/static-webserver/client/source/class/osparc/store/Services.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ qx.Class.define("osparc.store.Services", {
6767
const services = this.__servicesCached;
6868
if (key in services && version in services[key]) {
6969
const historyEntry = osparc.service.Utils.getHistoryEntry(services[key][version]);
70-
if (historyEntry["compatibility"] && historyEntry["compatibility"]["canUpdateTo"]) {
70+
if (historyEntry && historyEntry["compatibility"] && historyEntry["compatibility"]["canUpdateTo"]) {
7171
const canUpdateTo = historyEntry["compatibility"]["canUpdateTo"];
7272
return {
7373
key: "key" in canUpdateTo ? canUpdateTo["key"] : key, // key is optional

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

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,13 @@ qx.Theme.define("osparc.theme.Decoration", {
2626
}
2727
},
2828

29+
"separator-strong": {
30+
style: {
31+
widthTop: 1,
32+
colorTop: "product-color",
33+
}
34+
},
35+
2936
"border-simple": {
3037
include: "border",
3138
style: {

0 commit comments

Comments
 (0)