Skip to content

Commit 948de8b

Browse files
committed
CollaboratorsFunction
1 parent 0bbcd00 commit 948de8b

File tree

3 files changed

+208
-2
lines changed

3 files changed

+208
-2
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ qx.Class.define("osparc.data.Roles", {
7777
},
7878
}
7979
},
80-
// study & templates
80+
// study & templates & functions
8181
STUDY: {
8282
"read": {
8383
id: "read",

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

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,14 @@ qx.Class.define("osparc.data.model.Function", {
171171
},
172172

173173
canIWrite: function() {
174-
return Boolean(this.getAccessRights()["write"]);
174+
const accessRights = this.getAccessRights();
175+
const groupsStore = osparc.store.Groups.getInstance();
176+
const orgIDs = groupsStore.getOrganizationIds();
177+
orgIDs.push(groupsStore.getMyGroupId());
178+
if (orgIDs.length) {
179+
return osparc.share.CollaboratorsFunction.canGroupsWrite(accessRights, (orgIDs));
180+
}
181+
return false;
175182
},
176183

177184
patchFunction: function(functionChanges) {
Lines changed: 199 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,199 @@
1+
/* ************************************************************************
2+
3+
osparc - the simcore frontend
4+
5+
https://osparc.io
6+
7+
Copyright:
8+
2025 IT'IS Foundation, https://itis.swiss
9+
10+
License:
11+
MIT: https://opensource.org/licenses/MIT
12+
13+
Authors:
14+
* Odei Maiz (odeimaiz)
15+
16+
************************************************************************ */
17+
18+
19+
qx.Class.define("osparc.share.CollaboratorsFunction", {
20+
extend: osparc.share.Collaborators,
21+
22+
/**
23+
* @param functionData {Object} Object containing the serialized function Data
24+
*/
25+
construct: function(functionData) {
26+
this._resourceType = "function";
27+
const functionDataCopy = osparc.utils.Utils.deepCloneObject(functionData);
28+
29+
this.base(arguments, functionDataCopy);
30+
},
31+
32+
statics: {
33+
canGroupsWrite: function(accessRights, gIds) {
34+
let canWrite = false;
35+
for (let i=0; i<gIds.length && !canWrite; i++) {
36+
const gid = gIds[i];
37+
canWrite = (gid in accessRights) ? accessRights[gid]["write"] : false;
38+
}
39+
return canWrite;
40+
},
41+
42+
canGroupsDelete: function(accessRights, gIds) {
43+
let canWrite = false;
44+
for (let i=0; i<gIds.length && !canWrite; i++) {
45+
const gid = gIds[i];
46+
canWrite = (gid in accessRights) ? accessRights[gid]["delete"] : false;
47+
}
48+
return canWrite;
49+
},
50+
51+
__getDeleters: function(functionData) {
52+
const deleters = [];
53+
Object.entries(functionData["accessRights"]).forEach(([key, value]) => {
54+
if (value["delete"]) {
55+
deleters.push(key);
56+
}
57+
});
58+
return deleters;
59+
},
60+
61+
// checks that if the user to remove is an owner, there will still be another owner
62+
canCollaboratorBeRemoved: function(functionData, gid) {
63+
const ownerGids = this.__getDeleters(functionData);
64+
if (ownerGids.includes(gid.toString())) {
65+
return ownerGids.length > 1;
66+
}
67+
return true;
68+
},
69+
},
70+
71+
members: {
72+
_addEditors: function(gids, newAccessRights) {
73+
if (gids.length === 0) {
74+
return;
75+
}
76+
77+
const readAccessRole = osparc.data.Roles.STUDY["read"];
78+
const writeAccessRole = osparc.data.Roles.STUDY["write"];
79+
if (!newAccessRights) {
80+
newAccessRights = this._resourceType === "function" ? writeAccessRole.accessRights : readAccessRole.accessRights;
81+
}
82+
const resourceAlias = osparc.product.Utils.resourceTypeToAlias(this._resourceType, {firstUpperCase: true});
83+
const newCollaborators = {};
84+
gids.forEach(gid => {
85+
newCollaborators[gid] = newAccessRights;
86+
});
87+
osparc.store.function.getInstance().addCollaborators(this._serializedDataCopy, newCollaborators)
88+
.then(() => {
89+
const text = resourceAlias + this.tr(" successfully shared");
90+
osparc.FlashMessenger.logAs(text);
91+
this.fireDataEvent("updateAccessRights", this._serializedDataCopy);
92+
this._reloadCollaboratorsList();
93+
})
94+
.catch(err => osparc.FlashMessenger.logError(err, this.tr("Something went wrong while sharing the ") + resourceAlias));
95+
},
96+
97+
_deleteMember: function(collaborator, item) {
98+
if (item) {
99+
item.setEnabled(false);
100+
}
101+
102+
return osparc.store.function.getInstance().removeCollaborator(this._serializedDataCopy, collaborator["gid"])
103+
.then(() => {
104+
this.fireDataEvent("updateAccessRights", this._serializedDataCopy);
105+
osparc.FlashMessenger.logAs(collaborator["name"] + this.tr(" successfully removed"));
106+
this._reloadCollaboratorsList();
107+
})
108+
.catch(err => osparc.FlashMessenger.logError(err, this.tr("Something went wrong while removing ") + collaborator["name"]))
109+
.finally(() => {
110+
if (item) {
111+
item.setEnabled(true);
112+
}
113+
});
114+
},
115+
116+
__make: function(collaboratorGId, newAccessRights, successMsg, failureMsg, item) {
117+
item.setEnabled(false);
118+
119+
osparc.store.function.getInstance().updateCollaborator(this._serializedDataCopy, collaboratorGId, newAccessRights)
120+
.then(() => {
121+
this.fireDataEvent("updateAccessRights", this._serializedDataCopy);
122+
osparc.FlashMessenger.logAs(successMsg);
123+
this._reloadCollaboratorsList();
124+
})
125+
.catch(err => osparc.FlashMessenger.logError(err, failureMsg))
126+
.finally(() => {
127+
if (item) {
128+
item.setEnabled(true);
129+
}
130+
});
131+
},
132+
133+
_promoteToEditor: function(collaborator, item) {
134+
const writeAccessRole = osparc.data.Roles.STUDY["write"];
135+
this.__make(
136+
collaborator["gid"],
137+
writeAccessRole.accessRights,
138+
this.tr(`Successfully promoted to ${writeAccessRole.label}`),
139+
this.tr(`Something went wrong while promoting to ${writeAccessRole.label}`),
140+
item
141+
);
142+
},
143+
144+
_promoteToOwner: function(collaborator, item) {
145+
const deleteAccessRole = osparc.data.Roles.STUDY["delete"];
146+
this.__make(
147+
collaborator["gid"],
148+
deleteAccessRole.accessRights,
149+
this.tr(`Successfully promoted to ${deleteAccessRole.label}`),
150+
this.tr(`Something went wrong while promoting to ${deleteAccessRole.label}`),
151+
item
152+
);
153+
},
154+
155+
_demoteToUser: async function(collaborator, item) {
156+
const readAccessRole = osparc.data.Roles.STUDY["read"];
157+
const groupId = collaborator["gid"];
158+
const demoteToUser = (gid, itm) => {
159+
this.__make(
160+
gid,
161+
readAccessRole.accessRights,
162+
this.tr(`Successfully demoted to ${readAccessRole.label}`),
163+
this.tr(`Something went wrong while demoting to ${readAccessRole.label}`),
164+
itm
165+
);
166+
};
167+
168+
const organization = osparc.store.Groups.getInstance().getOrganization(groupId);
169+
if (organization) {
170+
const msg = this.tr(`Demoting to ${readAccessRole.label} will remove write access to all the members of the Organization. Are you sure?`);
171+
const win = new osparc.ui.window.Confirmation(msg).set({
172+
caption: this.tr("Demote"),
173+
confirmAction: "delete",
174+
confirmText: this.tr("Yes")
175+
});
176+
win.center();
177+
win.open();
178+
win.addListener("close", () => {
179+
if (win.getConfirmed()) {
180+
demoteToUser(groupId, item);
181+
}
182+
}, this);
183+
} else {
184+
demoteToUser(groupId, item);
185+
}
186+
},
187+
188+
_demoteToEditor: function(collaborator, item) {
189+
const writeAccessRole = osparc.data.Roles.STUDY["write"];
190+
this.__make(
191+
collaborator["gid"],
192+
writeAccessRole.accessRights,
193+
this.tr(`Successfully demoted to ${writeAccessRole.label}`),
194+
this.tr(`Something went wrong while demoting to ${writeAccessRole.label}`),
195+
item
196+
);
197+
},
198+
}
199+
});

0 commit comments

Comments
 (0)