Skip to content

Commit 78a2e27

Browse files
authored
✨ [Frontend] Connect folders to backend (#6151)
1 parent 4341733 commit 78a2e27

File tree

14 files changed

+542
-276
lines changed

14 files changed

+542
-276
lines changed

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

Lines changed: 24 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ qx.Class.define("osparc.dashboard.FolderButtonItem", {
4444

4545
events: {
4646
"folderSelected": "qx.event.type.Data",
47+
"folderUpdated": "qx.event.type.Data",
4748
"deleteFolderRequested": "qx.event.type.Data"
4849
},
4950

@@ -148,9 +149,9 @@ qx.Class.define("osparc.dashboard.FolderButtonItem", {
148149
__applyFolder: function(folder) {
149150
this.getChildControl("icon");
150151
this.set({
151-
cardKey: "folder-" + folder.getId()
152+
cardKey: "folder-" + folder.getFolderId()
152153
});
153-
folder.bind("id", this, "folderId");
154+
folder.bind("folderId", this, "folderId");
154155
folder.bind("parentId", this, "parentFolderId");
155156
folder.bind("name", this, "title");
156157
folder.bind("description", this, "description");
@@ -198,18 +199,18 @@ qx.Class.define("osparc.dashboard.FolderButtonItem", {
198199
folderEditor.addListener("updateFolder", () => {
199200
const newName = folderEditor.getLabel();
200201
const newDescription = folderEditor.getDescription();
201-
const promises = [];
202-
if (newName !== folder.getName()) {
203-
promises.push(osparc.data.model.Folder.patchFolder(this.getFolderId(), "name", newName));
204-
}
205-
if (newDescription !== folder.getDescription()) {
206-
promises.push(osparc.data.model.Folder.patchFolder(this.getFolderId(), "description", newDescription));
207-
}
208-
Promise.all(promises)
209-
.then(() => folder.set({
210-
name: newName,
211-
description: newDescription
212-
}))
202+
const updateData = {
203+
"name": newName,
204+
"description": newDescription
205+
};
206+
osparc.data.model.Folder.putFolder(this.getFolderId(), updateData)
207+
.then(() => {
208+
folder.set({
209+
name: newName,
210+
description: newDescription
211+
});
212+
this.fireDataEvent("folderUpdated", folder.getFolderId());
213+
})
213214
.catch(err => console.error(err));
214215
win.close();
215216
});
@@ -260,10 +261,15 @@ qx.Class.define("osparc.dashboard.FolderButtonItem", {
260261
},
261262

262263
__openShareWith: function() {
263-
const title = this.tr("Share Folder");
264-
const permissionsView = new osparc.share.CollaboratorsFolder(this.getFolder());
265-
osparc.ui.window.Window.popUpInWindow(permissionsView, title);
266-
permissionsView.addListener("updateAccessRights", () => this.__applyAccessRights(this.getFolder().getAccessRights()), this);
264+
const disableShare = true;
265+
if (disableShare) {
266+
osparc.FlashMessenger.getInstance().logAs(this.tr("Not yet implemented"), "WARNING");
267+
} else {
268+
const title = this.tr("Share Folder");
269+
const permissionsView = new osparc.share.CollaboratorsFolder(this.getFolder());
270+
osparc.ui.window.Window.popUpInWindow(permissionsView, title);
271+
permissionsView.addListener("updateAccessRights", () => this.__applyAccessRights(this.getFolder().getAccessRights()), this);
272+
}
267273
},
268274

269275
__deleteStudyRequested: function() {

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ qx.Class.define("osparc.dashboard.FolderHeader", {
117117
} else {
118118
folderButton = new qx.ui.form.Button(this.tr("Home"), "@FontAwesome5Solid/home/14");
119119
}
120-
folderButton.addListener("execute", () => this.fireDataEvent("changeCurrentFolderId", folder ? folder.getId() : null), this);
120+
folderButton.addListener("execute", () => this.fireDataEvent("changeCurrentFolderId", folder ? folder.getFolderId() : null), this);
121121
folderButton.set({
122122
backgroundColor: "transparent",
123123
textColor: "text",
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
/* ************************************************************************
2+
3+
osparc - the simcore frontend
4+
5+
https://osparc.io
6+
7+
Copyright:
8+
2024 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+
qx.Class.define("osparc.dashboard.FolderTreeItem", {
19+
extend: qx.ui.tree.VirtualTreeItem,
20+
21+
members: {
22+
_addWidgets: function() {
23+
this.addSpacer();
24+
// this.addOpenButton();
25+
const openButton = this.getChildControl("open");
26+
openButton.addListener("changeOpen", () => {
27+
console.log("changeOpen", this);
28+
}, this);
29+
openButton.addListener("changeVisibility", e => {
30+
// console.log("changeVisibility", this.getLabel() + e.getData(), this);
31+
openButton.show();
32+
}, this);
33+
this._add(openButton);
34+
this.addIcon();
35+
const label = this.getChildControl("label");
36+
this._add(label, {
37+
flex: 1
38+
});
39+
}
40+
}
41+
});
Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
/* ************************************************************************
2+
3+
osparc - the simcore frontend
4+
5+
https://osparc.io
6+
7+
Copyright:
8+
2024 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+
qx.Class.define("osparc.dashboard.FoldersTree", {
19+
extend: qx.ui.tree.VirtualTree,
20+
21+
construct: function() {
22+
const rootFolder = this.self().createNewEntry(null);
23+
const root = qx.data.marshal.Json.createModel(rootFolder, true);
24+
this.__fetchChildren(root);
25+
26+
this.base(arguments, root, "label", "children");
27+
28+
this.set({
29+
openMode: "dbltap",
30+
decorator: "no-border",
31+
font: "text-14",
32+
showLeafs: true,
33+
paddingLeft: -10,
34+
});
35+
36+
this.__initTree();
37+
},
38+
39+
events: {
40+
"selectionChanged": "qx.event.type.Event" // tap
41+
},
42+
43+
statics: {
44+
createNewEntry: function(folder) {
45+
return {
46+
folderId: folder ? folder.getFolderId() : null,
47+
label: folder ? folder.getName() : "Home",
48+
children: [
49+
this.self().getLoadingData()
50+
],
51+
loaded: false,
52+
};
53+
},
54+
55+
getLoadingData: function() {
56+
return {
57+
folderId: -1,
58+
label: "Loading...",
59+
children: [],
60+
icon: "@FontAwesome5Solid/circle-notch/12",
61+
loaded: false,
62+
};
63+
},
64+
65+
addLoadingChild: function(parentModel) {
66+
const loadingModel = qx.data.marshal.Json.createModel(this.self().getLoadingData(), true);
67+
parentModel.getChildren().append(loadingModel);
68+
},
69+
70+
removeLoadingChild: function(parent) {
71+
for (let i = parent.getChildren().getLength() - 1; i >= 0; i--) {
72+
if (parent.getChildren().toArray()[i].getLabel() === "Loading...") {
73+
parent.getChildren().splice(i, 1);
74+
}
75+
}
76+
}
77+
},
78+
79+
members: {
80+
__initTree: function() {
81+
const that = this;
82+
this.setDelegate({
83+
createItem: () => new osparc.dashboard.FolderTreeItem(),
84+
bindItem: (c, item, id) => {
85+
c.bindDefaultProperties(item, id);
86+
c.bindProperty("folderId", "model", null, item, id);
87+
c.bindProperty("", "open", {
88+
converter(value, _, __, target) {
89+
const isOpen = target.isOpen();
90+
if (isOpen && !value.getLoaded()) {
91+
// eslint-disable-next-line no-underscore-dangle
92+
that.__fetchChildren(value);
93+
}
94+
return isOpen;
95+
}
96+
}, item, id);
97+
},
98+
configureItem: item => {
99+
item.addListener("tap", () => this.fireDataEvent("selectionChanged", item.getModel()), this);
100+
},
101+
sorter: (a, b) => {
102+
const aLabel = a.getLabel();
103+
if (aLabel === -1) {
104+
return 1;
105+
}
106+
const bLabel = b.getLabel();
107+
if (bLabel === -1) {
108+
return -1;
109+
}
110+
return aLabel - bLabel;
111+
}
112+
});
113+
},
114+
115+
__fetchChildren: function(parentModel) {
116+
parentModel.setLoaded(true);
117+
118+
const folderId = parentModel.getFolderId ? parentModel.getFolderId() : parentModel.getModel();
119+
osparc.store.Folders.getInstance().fetchFolders(folderId)
120+
.then(folders => {
121+
this.self().removeLoadingChild(parentModel);
122+
folders.forEach(folder => {
123+
const folderData = this.self().createNewEntry(folder);
124+
const folderModel = qx.data.marshal.Json.createModel(folderData, true);
125+
parentModel.getChildren().append(folderModel);
126+
});
127+
})
128+
.catch(console.error);
129+
}
130+
}
131+
});
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
/* ************************************************************************
2+
3+
osparc - the simcore frontend
4+
5+
https://osparc.io
6+
7+
Copyright:
8+
2024 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+
qx.Class.define("osparc.dashboard.MoveStudyToFolder", {
19+
extend: qx.ui.core.Widget,
20+
21+
construct: function(studyData, currentFolderId) {
22+
this.base(arguments);
23+
24+
this.__studyData = studyData;
25+
this.__currentFolderId = currentFolderId;
26+
27+
this._setLayout(new qx.ui.layout.VBox(10));
28+
29+
this.getChildControl("current-folder");
30+
const foldersTree = this.getChildControl("folders-tree");
31+
this.getChildControl("cancel-btn");
32+
const moveButton = this.getChildControl("move-btn");
33+
34+
moveButton.setEnabled(false)
35+
foldersTree.addListener("selectionChanged", e => {
36+
const folderId = e.getData();
37+
moveButton.setEnabled(this.__currentFolderId !== folderId);
38+
moveButton.addListenerOnce("execute", () => this.fireDataEvent("moveToFolder", folderId));
39+
});
40+
},
41+
42+
events: {
43+
"cancel": "qx.event.type.Event",
44+
"moveToFolder": "qx.event.type.Data"
45+
},
46+
47+
members: {
48+
__studyData: null,
49+
__currentFolderId: null,
50+
51+
_createChildControlImpl: function(id) {
52+
let control;
53+
switch (id) {
54+
case "current-folder": {
55+
const folder = osparc.store.Folders.getInstance().getFolder(this.__currentFolderId);
56+
const currentFolderName = folder ? folder["name"] : "Home";
57+
control = new qx.ui.basic.Label(this.tr("Current location: ") + currentFolderName);
58+
this._add(control);
59+
break;
60+
}
61+
case "folders-tree":
62+
control = new osparc.dashboard.FoldersTree();
63+
this._add(control);
64+
break;
65+
case "buttons-layout":
66+
control = new qx.ui.container.Composite(new qx.ui.layout.HBox(10).set({
67+
alignX: "right"
68+
}));
69+
this._add(control);
70+
break;
71+
case "cancel-btn": {
72+
const buttons = this.getChildControl("buttons-layout");
73+
control = new qx.ui.form.Button(this.tr("Cancel")).set({
74+
appearance: "form-button-text"
75+
});
76+
control.addListener("execute", () => this.fireEvent("cancel"), this);
77+
buttons.add(control);
78+
break;
79+
}
80+
case "move-btn": {
81+
const buttons = this.getChildControl("buttons-layout");
82+
control = new qx.ui.form.Button(this.tr("Move")).set({
83+
appearance: "form-button"
84+
});
85+
buttons.add(control);
86+
break;
87+
}
88+
}
89+
return control || this.base(arguments, id);
90+
}
91+
}
92+
});

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -252,6 +252,7 @@ qx.Class.define("osparc.dashboard.ResourceBrowserBase", {
252252
resourcesContainer.addListener("tagClicked", e => this._searchBarFilter.addTagActiveFilter(e.getData()));
253253
resourcesContainer.addListener("emptyStudyClicked", e => this._deleteResourceRequested(e.getData()));
254254
resourcesContainer.addListener("folderSelected", e => this._folderSelected(e.getData()));
255+
resourcesContainer.addListener("folderUpdated", e => this._folderUpdated(e.getData()));
255256
resourcesContainer.addListener("deleteFolderRequested", e => this._deleteFolderRequested(e.getData()));
256257
this._addToLayout(resourcesContainer);
257258
},
@@ -451,6 +452,10 @@ qx.Class.define("osparc.dashboard.ResourceBrowserBase", {
451452
throw new Error("Abstract method called!");
452453
},
453454

455+
_folderUpdated: function(folderId) {
456+
throw new Error("Abstract method called!");
457+
},
458+
454459
_deleteFolderRequested: function(folderId) {
455460
throw new Error("Abstract method called!");
456461
},

0 commit comments

Comments
 (0)