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 1c18a4a3aed..1cd8440fc45 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
@@ -99,7 +99,7 @@ qx.Class.define("osparc.auth.ui.LoginView", {
this.fireEvent("toRegister");
} else if (createAccountAction === "REQUEST_ACCOUNT_FORM") {
this.fireEvent("toRequestAccount");
- } else if (createAccountAction === "REQUEST_ACCOUNT_FORM") {
+ } else if (createAccountAction === "REQUEST_ACCOUNT_INSTRUCTIONS") {
osparc.store.Support.openInvitationRequiredDialog();
}
createAccountBtn.setEnabled(true);
diff --git a/services/static-webserver/client/source/class/osparc/dashboard/FolderButtonItem.js b/services/static-webserver/client/source/class/osparc/dashboard/FolderButtonItem.js
index d6a0d76769d..9db4130e02b 100644
--- a/services/static-webserver/client/source/class/osparc/dashboard/FolderButtonItem.js
+++ b/services/static-webserver/client/source/class/osparc/dashboard/FolderButtonItem.js
@@ -45,6 +45,8 @@ qx.Class.define("osparc.dashboard.FolderButtonItem", {
events: {
"folderSelected": "qx.event.type.Data",
"folderUpdated": "qx.event.type.Data",
+ "moveFolderToFolderRequested": "qx.event.type.Data",
+ "moveFolderToWorkspaceRequested": "qx.event.type.Data",
"deleteFolderRequested": "qx.event.type.Data"
},
@@ -73,12 +75,6 @@ qx.Class.define("osparc.dashboard.FolderButtonItem", {
apply: "__applyTitle"
},
- description: {
- check: "String",
- nullable: true,
- apply: "__applyDescription"
- },
-
lastModified: {
check: "Date",
nullable: true,
@@ -143,7 +139,6 @@ qx.Class.define("osparc.dashboard.FolderButtonItem", {
folder.bind("folderId", this, "folderId");
folder.bind("parentId", this, "parentFolderId");
folder.bind("name", this, "title");
- folder.bind("description", this, "description");
folder.bind("lastModified", this, "lastModified");
this.__addMenuButton();
@@ -152,11 +147,6 @@ qx.Class.define("osparc.dashboard.FolderButtonItem", {
__applyTitle: function(value) {
const label = this.getChildControl("title");
label.setValue(value);
- this.__updateTooltip();
- },
-
- __applyDescription: function() {
- this.__updateTooltip();
},
__applyLastModified: function(value) {
@@ -175,37 +165,19 @@ qx.Class.define("osparc.dashboard.FolderButtonItem", {
});
const editButton = new qx.ui.menu.Button(this.tr("Rename..."), "@FontAwesome5Solid/pencil-alt/12");
- editButton.addListener("execute", () => {
- const folder = this.getFolder();
- const newFolder = false;
- const folderEditor = new osparc.editor.FolderEditor(newFolder).set({
- label: folder.getName(),
- description: folder.getDescription()
- });
- const title = this.tr("Edit Folder");
- const win = osparc.ui.window.Window.popUpInWindow(folderEditor, title, 300, 200);
- folderEditor.addListener("updateFolder", () => {
- const newName = folderEditor.getLabel();
- const newDescription = folderEditor.getDescription();
- const updateData = {
- "name": newName,
- "description": newDescription
- };
- osparc.data.model.Folder.putFolder(this.getFolderId(), updateData)
- .then(() => {
- folder.set({
- name: newName,
- description: newDescription
- });
- this.fireDataEvent("folderUpdated", folder.getFolderId());
- })
- .catch(err => console.error(err));
- win.close();
- });
- folderEditor.addListener("cancel", () => win.close());
- });
+ editButton.addListener("execute", () => this.__editFolder(), this);
menu.add(editButton);
+ const moveToFolderButton = new qx.ui.menu.Button(this.tr("Move to Folder..."), "@FontAwesome5Solid/folder/12");
+ moveToFolderButton.addListener("execute", () => this.fireDataEvent("moveFolderToFolderRequested", this.getFolderId()), this);
+ menu.add(moveToFolderButton);
+
+ const moveToWorkspaceButton = new qx.ui.menu.Button(this.tr("Move to Workspace..."), "");
+ moveToWorkspaceButton.addListener("execute", () => this.fireDataEvent("moveFolderToWorkspaceRequested", this.getFolderId()), this);
+ menu.add(moveToWorkspaceButton);
+
+ menu.addSeparator();
+
const deleteButton = new qx.ui.menu.Button(this.tr("Delete"), "@FontAwesome5Solid/trash/12");
deleteButton.addListener("execute", () => this.__deleteStudyRequested(), this);
menu.add(deleteButton);
@@ -213,13 +185,6 @@ qx.Class.define("osparc.dashboard.FolderButtonItem", {
menuButton.setMenu(menu);
},
- __updateTooltip: function() {
- const toolTipText = this.getTitle() + (this.getDescription() ? "
" + this.getDescription() : "");
- this.set({
- toolTipText
- })
- },
-
__itemSelected: function(newVal) {
if (newVal) {
this.fireDataEvent("folderSelected", this.getFolderId());
@@ -227,6 +192,32 @@ qx.Class.define("osparc.dashboard.FolderButtonItem", {
this.setValue(false);
},
+ __editFolder: function() {
+ const folder = this.getFolder();
+ const newFolder = false;
+ const folderEditor = new osparc.editor.FolderEditor(newFolder).set({
+ label: folder.getName(),
+ });
+ const title = this.tr("Edit Folder");
+ const win = osparc.ui.window.Window.popUpInWindow(folderEditor, title, 300, 150);
+ folderEditor.addListener("updateFolder", () => {
+ const newName = folderEditor.getLabel();
+ const updateData = {
+ "name": newName,
+ };
+ osparc.data.model.Folder.putFolder(this.getFolderId(), updateData)
+ .then(() => {
+ folder.set({
+ name: newName,
+ });
+ this.fireDataEvent("folderUpdated", folder.getFolderId());
+ })
+ .catch(err => console.error(err));
+ win.close();
+ });
+ folderEditor.addListener("cancel", () => win.close());
+ },
+
__deleteStudyRequested: function() {
const msg = this.tr("Are you sure you want to delete") + " " + this.getTitle() + "?";
const confirmationWin = new osparc.ui.window.Confirmation(msg).set({
diff --git a/services/static-webserver/client/source/class/osparc/dashboard/FolderButtonNew.js b/services/static-webserver/client/source/class/osparc/dashboard/FolderButtonNew.js
index e0b0eb1aef6..1f0e862c726 100644
--- a/services/static-webserver/client/source/class/osparc/dashboard/FolderButtonNew.js
+++ b/services/static-webserver/client/source/class/osparc/dashboard/FolderButtonNew.js
@@ -80,13 +80,11 @@ qx.Class.define("osparc.dashboard.FolderButtonNew", {
const newFolder = true;
const folderEditor = new osparc.editor.FolderEditor(newFolder);
const title = this.tr("New Folder");
- const win = osparc.ui.window.Window.popUpInWindow(folderEditor, title, 300, 200);
+ const win = osparc.ui.window.Window.popUpInWindow(folderEditor, title, 300, 150);
folderEditor.addListener("createFolder", () => {
const name = folderEditor.getLabel();
- const description = folderEditor.getDescription();
this.fireDataEvent("createFolder", {
name,
- description
});
win.close();
});
diff --git a/services/static-webserver/client/source/class/osparc/dashboard/FoldersTree.js b/services/static-webserver/client/source/class/osparc/dashboard/FoldersTree.js
index 2a597b08b92..059a01c49f2 100644
--- a/services/static-webserver/client/source/class/osparc/dashboard/FoldersTree.js
+++ b/services/static-webserver/client/source/class/osparc/dashboard/FoldersTree.js
@@ -18,8 +18,11 @@
qx.Class.define("osparc.dashboard.FoldersTree", {
extend: qx.ui.tree.VirtualTree,
- construct: function() {
- const rootFolder = this.self().createNewEntry(null);
+ construct: function(currentWorkspaceId) {
+ this.__currentWorkspaceId = currentWorkspaceId;
+ const workspace = osparc.store.Workspaces.getWorkspace(currentWorkspaceId);
+ const rootLabel = workspace ? workspace.getName() : "My Workspace";
+ const rootFolder = this.self().createNewEntry(rootLabel, null);
const root = qx.data.marshal.Json.createModel(rootFolder, true);
this.__fetchChildren(root);
@@ -41,10 +44,10 @@ qx.Class.define("osparc.dashboard.FoldersTree", {
},
statics: {
- createNewEntry: function(folder) {
+ createNewEntry: function(label, folderId) {
return {
- folderId: folder ? folder.getFolderId() : null,
- label: folder ? folder.getName() : "Home",
+ label,
+ folderId,
children: [
this.self().getLoadingData()
],
@@ -77,6 +80,8 @@ qx.Class.define("osparc.dashboard.FoldersTree", {
},
members: {
+ __currentWorkspaceId:null,
+
__initTree: function() {
const that = this;
this.setDelegate({
@@ -116,11 +121,11 @@ qx.Class.define("osparc.dashboard.FoldersTree", {
parentModel.setLoaded(true);
const folderId = parentModel.getFolderId ? parentModel.getFolderId() : parentModel.getModel();
- osparc.store.Folders.getInstance().fetchFolders(folderId)
+ osparc.store.Folders.getInstance().fetchFolders(folderId, this.__currentWorkspaceId)
.then(folders => {
this.self().removeLoadingChild(parentModel);
folders.forEach(folder => {
- const folderData = this.self().createNewEntry(folder);
+ const folderData = this.self().createNewEntry(folder.getName(), folder.getFolderId());
const folderModel = qx.data.marshal.Json.createModel(folderData, true);
parentModel.getChildren().append(folderModel);
});
diff --git a/services/static-webserver/client/source/class/osparc/dashboard/MoveStudyToFolder.js b/services/static-webserver/client/source/class/osparc/dashboard/MoveResourceToFolder.js
similarity index 85%
rename from services/static-webserver/client/source/class/osparc/dashboard/MoveStudyToFolder.js
rename to services/static-webserver/client/source/class/osparc/dashboard/MoveResourceToFolder.js
index f01d64f42b4..e01bc834776 100644
--- a/services/static-webserver/client/source/class/osparc/dashboard/MoveStudyToFolder.js
+++ b/services/static-webserver/client/source/class/osparc/dashboard/MoveResourceToFolder.js
@@ -15,14 +15,14 @@
************************************************************************ */
-qx.Class.define("osparc.dashboard.MoveStudyToFolder", {
+qx.Class.define("osparc.dashboard.MoveResourceToFolder", {
extend: qx.ui.core.Widget,
- construct: function(studyData, currentFolderId) {
+ construct: function(currentFolderId, currentWorkspaceId) {
this.base(arguments);
- this.__studyData = studyData;
this.__currentFolderId = currentFolderId;
+ this.__currentWorkspaceId = currentWorkspaceId;
this._setLayout(new qx.ui.layout.VBox(10));
@@ -35,7 +35,10 @@ qx.Class.define("osparc.dashboard.MoveStudyToFolder", {
foldersTree.addListener("selectionChanged", e => {
const folderId = e.getData();
moveButton.setEnabled(this.__currentFolderId !== folderId);
- moveButton.addListenerOnce("execute", () => this.fireDataEvent("moveToFolder", folderId));
+ this.__selectedFolderId = folderId;
+ });
+ moveButton.addListener("execute", () => {
+ this.fireDataEvent("moveToFolder", this.__selectedFolderId);
});
},
@@ -45,7 +48,6 @@ qx.Class.define("osparc.dashboard.MoveStudyToFolder", {
},
members: {
- __studyData: null,
__currentFolderId: null,
_createChildControlImpl: function(id) {
@@ -59,7 +61,7 @@ qx.Class.define("osparc.dashboard.MoveStudyToFolder", {
break;
}
case "folders-tree":
- control = new osparc.dashboard.FoldersTree();
+ control = new osparc.dashboard.FoldersTree(this.__currentWorkspaceId);
this._add(control);
break;
case "buttons-layout":
diff --git a/services/static-webserver/client/source/class/osparc/dashboard/MoveResourceToWorkspace.js b/services/static-webserver/client/source/class/osparc/dashboard/MoveResourceToWorkspace.js
new file mode 100644
index 00000000000..56e9d5a674f
--- /dev/null
+++ b/services/static-webserver/client/source/class/osparc/dashboard/MoveResourceToWorkspace.js
@@ -0,0 +1,93 @@
+/* ************************************************************************
+
+ osparc - the simcore frontend
+
+ https://osparc.io
+
+ Copyright:
+ 2024 IT'IS Foundation, https://itis.swiss
+
+ License:
+ MIT: https://opensource.org/licenses/MIT
+
+ Authors:
+ * Odei Maiz (odeimaiz)
+
+************************************************************************ */
+
+qx.Class.define("osparc.dashboard.MoveResourceToWorkspace", {
+ extend: qx.ui.core.Widget,
+
+ construct: function(currentWorkspaceId) {
+ this.base(arguments);
+
+ this.__currentWorkspaceId = currentWorkspaceId;
+
+ this._setLayout(new qx.ui.layout.VBox(10));
+
+ this.getChildControl("current-workspace");
+ const workspacesTree = this.getChildControl("workspaces-tree");
+ this.getChildControl("cancel-btn");
+ const moveButton = this.getChildControl("move-btn");
+
+ moveButton.setEnabled(false)
+ workspacesTree.addListener("selectionChanged", e => {
+ const workspaceId = e.getData();
+ moveButton.setEnabled(this.__currentWorkspaceId !== workspaceId);
+ this.__selectedWorkspaceId = workspaceId;
+ });
+ moveButton.addListener("execute", () => {
+ this.fireDataEvent("moveToWorkspace", this.__selectedWorkspaceId);
+ }, this);
+ },
+
+ events: {
+ "cancel": "qx.event.type.Event",
+ "moveToWorkspace": "qx.event.type.Data"
+ },
+
+ members: {
+ __currentWorkspaceId: null,
+
+ _createChildControlImpl: function(id) {
+ let control;
+ switch (id) {
+ case "current-workspace": {
+ const workspace = osparc.store.Workspaces.getWorkspace(this.__currentWorkspaceId);
+ const currentWorkspaceName = workspace ? workspace.getName() : "My Workspace";
+ control = new qx.ui.basic.Label(this.tr("Current location: ") + currentWorkspaceName);
+ this._add(control);
+ break;
+ }
+ case "workspaces-tree":
+ control = new osparc.dashboard.WorkspacesTree();
+ this._add(control);
+ break;
+ case "buttons-layout":
+ control = new qx.ui.container.Composite(new qx.ui.layout.HBox(10).set({
+ alignX: "right"
+ }));
+ this._add(control);
+ break;
+ case "cancel-btn": {
+ const buttons = this.getChildControl("buttons-layout");
+ control = new qx.ui.form.Button(this.tr("Cancel")).set({
+ appearance: "form-button-text"
+ });
+ control.addListener("execute", () => this.fireEvent("cancel"), this);
+ buttons.add(control);
+ break;
+ }
+ case "move-btn": {
+ const buttons = this.getChildControl("buttons-layout");
+ control = new qx.ui.form.Button(this.tr("Move")).set({
+ appearance: "form-button"
+ });
+ buttons.add(control);
+ break;
+ }
+ }
+ return control || this.base(arguments, id);
+ }
+ }
+});
diff --git a/services/static-webserver/client/source/class/osparc/dashboard/ResourceBrowserBase.js b/services/static-webserver/client/source/class/osparc/dashboard/ResourceBrowserBase.js
index 40178ea468d..59bde762e2e 100644
--- a/services/static-webserver/client/source/class/osparc/dashboard/ResourceBrowserBase.js
+++ b/services/static-webserver/client/source/class/osparc/dashboard/ResourceBrowserBase.js
@@ -186,6 +186,7 @@ qx.Class.define("osparc.dashboard.ResourceBrowserBase", {
members: {
__leftFilters: null,
+ _resourceFilter: null,
__centerLayout: null,
_resourceType: null,
_resourcesList: null,
@@ -252,11 +253,13 @@ qx.Class.define("osparc.dashboard.ResourceBrowserBase", {
resourcesContainer.addListener("emptyStudyClicked", e => this._deleteResourceRequested(e.getData()));
resourcesContainer.addListener("folderSelected", e => this._folderSelected(e.getData()));
resourcesContainer.addListener("folderUpdated", e => this._folderUpdated(e.getData()));
+ resourcesContainer.addListener("moveFolderToFolderRequested", e => this._moveFolderToFolderRequested(e.getData()));
+ resourcesContainer.addListener("moveFolderToWorkspaceRequested", e => this._moveFolderToWorkspaceRequested(e.getData()));
resourcesContainer.addListener("deleteFolderRequested", e => this._deleteFolderRequested(e.getData()));
resourcesContainer.addListener("workspaceSelected", e => {
const workspaceId = e.getData();
this._workspaceSelected(workspaceId);
- this.__resourceFilter.workspaceSelected(workspaceId);
+ this._resourceFilter.workspaceSelected(workspaceId);
});
resourcesContainer.addListener("workspaceUpdated", e => this._workspaceUpdated(e.getData()));
resourcesContainer.addListener("deleteWorkspaceRequested", e => this._deleteWorkspaceRequested(e.getData()));
@@ -355,7 +358,7 @@ qx.Class.define("osparc.dashboard.ResourceBrowserBase", {
},
_addResourceFilter: function() {
- const resourceFilter = this.__resourceFilter = new osparc.dashboard.ResourceFilter(this._resourceType).set({
+ const resourceFilter = this._resourceFilter = new osparc.dashboard.ResourceFilter(this._resourceType).set({
marginTop: osparc.dashboard.SearchBarFilter.HEIGHT + 10, // aligned with toolbar buttons: search bar + spacing
maxWidth: this.self().SIDE_SPACER_WIDTH,
width: this.self().SIDE_SPACER_WIDTH
@@ -473,6 +476,14 @@ qx.Class.define("osparc.dashboard.ResourceBrowserBase", {
throw new Error("Abstract method called!");
},
+ _moveFolderToFolderRequested: function(folderId) {
+ throw new Error("Abstract method called!");
+ },
+
+ _moveFolderToWorkspaceRequested: function(folderId) {
+ throw new Error("Abstract method called!");
+ },
+
_deleteFolderRequested: function(folderId) {
throw new Error("Abstract method called!");
},
diff --git a/services/static-webserver/client/source/class/osparc/dashboard/ResourceContainerManager.js b/services/static-webserver/client/source/class/osparc/dashboard/ResourceContainerManager.js
index 84b2e680f5f..4f7363299fe 100644
--- a/services/static-webserver/client/source/class/osparc/dashboard/ResourceContainerManager.js
+++ b/services/static-webserver/client/source/class/osparc/dashboard/ResourceContainerManager.js
@@ -86,6 +86,8 @@ qx.Class.define("osparc.dashboard.ResourceContainerManager", {
"changeVisibility": "qx.event.type.Data",
"folderSelected": "qx.event.type.Data",
"folderUpdated": "qx.event.type.Data",
+ "moveFolderToFolderRequested": "qx.event.type.Data",
+ "moveFolderToWorkspaceRequested": "qx.event.type.Data",
"deleteFolderRequested": "qx.event.type.Data",
"workspaceSelected": "qx.event.type.Data",
"workspaceUpdated": "qx.event.type.Data",
@@ -384,6 +386,8 @@ qx.Class.define("osparc.dashboard.ResourceContainerManager", {
[
"folderSelected",
"folderUpdated",
+ "moveFolderToFolderRequested",
+ "moveFolderToWorkspaceRequested",
"deleteFolderRequested",
].forEach(eName => card.addListener(eName, e => this.fireDataEvent(eName, e.getData())));
return card;
diff --git a/services/static-webserver/client/source/class/osparc/dashboard/ResourceFilter.js b/services/static-webserver/client/source/class/osparc/dashboard/ResourceFilter.js
index 0a47f4e12ec..4a93a2b0d00 100644
--- a/services/static-webserver/client/source/class/osparc/dashboard/ResourceFilter.js
+++ b/services/static-webserver/client/source/class/osparc/dashboard/ResourceFilter.js
@@ -43,6 +43,8 @@ qx.Class.define("osparc.dashboard.ResourceFilter", {
members: {
__resourceType: null,
+ __contextLayout: null,
+ __contextRadioGroup: null,
__sharedWithButtons: null,
__workspaceButtons: null,
__tagButtons: null,
@@ -70,9 +72,9 @@ qx.Class.define("osparc.dashboard.ResourceFilter", {
/* SHARED WITH */
__createSharedWithFilterLayout: function() {
- const layout = new qx.ui.container.Composite(new qx.ui.layout.VBox(5));
+ const layout = this.__contextLayout = new qx.ui.container.Composite(new qx.ui.layout.VBox(5));
- const radioGroup = new qx.ui.form.RadioGroup();
+ const radioGroup = this.__contextRadioGroup = new qx.ui.form.RadioGroup();
radioGroup.setAllowEmptySelection(false);
const options = osparc.dashboard.SearchBarFilter.getSharedWithOptions(this.__resourceType);
@@ -90,7 +92,15 @@ qx.Class.define("osparc.dashboard.ResourceFilter", {
button.set({
label: this.tr("My Workspace")
});
- } else {
+ } else if (option.id === "shared-with-me") {
+ button.set({
+ label: this.tr("Shared") + " " + osparc.product.Utils.getStudyAlias({
+ firstUpperCase: true,
+ plural: true,
+ })
+ });
+ }
+ if (option.id !== "show-all") {
button.set({
marginLeft: 15
});
@@ -112,7 +122,7 @@ qx.Class.define("osparc.dashboard.ResourceFilter", {
});
if (this.__resourceType === "study") {
- this.__addWorkspaceButtons(layout, radioGroup);
+ this.__addWorkspaceButtons();
}
return layout;
@@ -120,19 +130,30 @@ qx.Class.define("osparc.dashboard.ResourceFilter", {
/* /SHARED WITH */
/* WORKSPACES */
- __addWorkspaceButtons: function(layout, radioGroup) {
- layout.add(new qx.ui.core.Spacer());
+ __addWorkspaceButtons: function() {
+ this.__contextLayout.add(new qx.ui.core.Spacer());
const workspacesButton = new qx.ui.toolbar.RadioButton(this.tr("Shared Workspaces"), osparc.store.Workspaces.iconPath(22));
workspacesButton.workspaceId = -1;
workspacesButton.set({
appearance: "filter-toggle-button"
});
- layout.add(workspacesButton);
- radioGroup.add(workspacesButton);
+ this.__contextLayout.add(workspacesButton);
+ this.__contextRadioGroup.add(workspacesButton);
workspacesButton.addListener("execute", () => {
this.fireDataEvent("changeWorkspace", workspacesButton.workspaceId);
});
+ this.reloadWorkspaceButtons();
+ },
+
+ reloadWorkspaceButtons: function() {
+ // remove first the workspaces
+ for (let i=this.__workspaceButtons.length-1; i >= 0; i--) {
+ const workspaceButton = this.__workspaceButtons[i];
+ this.__contextLayout.remove(workspaceButton);
+ this.__contextRadioGroup.remove(workspaceButton);
+ }
+ this.__workspaceButtons = [];
osparc.store.Workspaces.fetchWorkspaces()
.then(workspaces => {
workspaces.forEach(workspace => {
@@ -143,8 +164,8 @@ qx.Class.define("osparc.dashboard.ResourceFilter", {
appearance: "filter-toggle-button",
marginLeft: 15,
});
- layout.add(workspaceButton);
- radioGroup.add(workspaceButton);
+ this.__contextLayout.add(workspaceButton);
+ this.__contextRadioGroup.add(workspaceButton);
workspaceButton.addListener("execute", () => {
this.fireDataEvent("changeWorkspace", workspaceButton.workspaceId);
}, this);
diff --git a/services/static-webserver/client/source/class/osparc/dashboard/StudyBrowser.js b/services/static-webserver/client/source/class/osparc/dashboard/StudyBrowser.js
index e9b61fadca7..1e288034fbc 100644
--- a/services/static-webserver/client/source/class/osparc/dashboard/StudyBrowser.js
+++ b/services/static-webserver/client/source/class/osparc/dashboard/StudyBrowser.js
@@ -102,19 +102,14 @@ qx.Class.define("osparc.dashboard.StudyBrowser", {
},
members: {
+ __currentRequest: null,
__workspacesList: null,
__foldersList: null,
// overridden
initResources: function() {
this._resourcesList = [];
- const promises = [
- this.__getActiveStudy()
- ];
- if (osparc.utils.DisabledPlugins.isFoldersEnabled()) {
- promises.push(osparc.store.Folders.getInstance().fetchFolders());
- }
- Promise.all(promises)
+ this.__getActiveStudy()
.then(() => {
this.getChildControl("resources-layout");
this.__attachEventHandlers();
@@ -175,70 +170,83 @@ qx.Class.define("osparc.dashboard.StudyBrowser", {
},
__reloadFolders: function() {
- const folders = osparc.store.Folders.getInstance().getFolders(this.getCurrentFolderId())
- this.__setFoldersToList(folders);
+ if (osparc.utils.DisabledPlugins.isFoldersEnabled()) {
+ const folderId = this.getCurrentFolderId();
+ const workspaceId = this.getCurrentWorkspaceId();
+ if (workspaceId === -1) {
+ return;
+ }
+ osparc.store.Folders.getInstance().fetchFolders(folderId, workspaceId)
+ .then(folders => {
+ this.__setFoldersToList(folders);
+ })
+ .catch(console.error);
+ }
},
__reloadStudies: function() {
if (this._loadingResourcesBtn.isFetching()) {
return;
}
+ const workspaceId = this.getCurrentWorkspaceId();
+ if (workspaceId === -1) {
+ return;
+ }
+
osparc.data.Resources.get("tasks")
.then(tasks => {
if (tasks && tasks.length) {
this.__tasksReceived(tasks);
}
});
+
+ // Show "Contact Us" message if services.length === 0
+ // Most probably is a product-stranger user (it can also be that the catalog is down)
+ osparc.store.Services.getServicesLatest()
+ .then(services => {
+ if (Object.keys(services).length === 0) {
+ const noAccessText = new qx.ui.basic.Label().set({
+ selectable: true,
+ rich: true,
+ font: "text-18",
+ paddingTop: 20
+ });
+ let msg = this.tr("It seems you don't have access to this product.");
+ msg += "";
+ msg += "";
+ msg += this.tr("Please contact us:");
+ msg += "";
+ const supportEmail = osparc.store.VendorInfo.getInstance().getSupportEmail();
+ noAccessText.setValue(msg + supportEmail);
+ this._addToLayout(noAccessText);
+ }
+ });
+
this._loadingResourcesBtn.setFetching(true);
this._loadingResourcesBtn.setVisibility("visible");
- const request = this.__getNextRequest();
- request
+ if (this.__currentRequest) {
+ // cancel currentRequest
+ }
+ const currentRequest = this.__currentRequest = this.__getNextStudiesRequest();
+ currentRequest
.then(resp => {
const studies = resp["data"];
this._resourcesContainer.getFlatList().nextRequest = resp["_links"]["next"];
this.__addStudiesToList(studies);
- // Show "Contact Us" message if studies.length === 0 && templates.length === 0 && services.length === 0
- // Most probably is a product-stranger user (it can also be that the catalog is down)
- const nStudies = "_meta" in resp ? resp["_meta"]["total"] : 0;
- if (nStudies === 0) {
- const promises = [
- osparc.store.Store.getInstance().getTemplates(),
- osparc.store.Services.getServicesLatest(),
- ];
- if (osparc.utils.DisabledPlugins.isFoldersEnabled()) {
- promises.push(osparc.store.Folders.getInstance().fetchFolders());
- }
- Promise.all(promises).then(values => {
- const templates = values[0];
- const services = values[1];
- if (templates.length === 0 && Object.keys(services).length === 0) {
- const noAccessText = new qx.ui.basic.Label().set({
- selectable: true,
- rich: true,
- font: "text-18",
- paddingTop: 20
- });
- let msg = this.tr("It seems you don't have access to this product.");
- msg += "";
- msg += "";
- msg += this.tr("Please contact us:");
- msg += "";
- const supportEmail = osparc.store.VendorInfo.getInstance().getSupportEmail();
- noAccessText.setValue(msg + supportEmail);
- this._addAt(noAccessText, 2);
- }
- });
- }
-
- // Show Quick Start if studies.length === 0
+ // Show Quick Start if there are no studies in the root folder of the personal workspace
const quickStart = osparc.product.quickStart.Utils.getQuickStart();
if (quickStart) {
const dontShow = osparc.utils.Utils.localCache.getLocalStorageItem(quickStart.localStorageStr);
if (dontShow === "true") {
return;
}
- if (nStudies === 0) {
+ const nStudies = "_meta" in resp ? resp["_meta"]["total"] : 0;
+ if (
+ nStudies === 0 &&
+ this.getWorkspaceId() === null &&
+ this.getCurrentFolderId() === null
+ ) {
const tutorialWindow = quickStart.tutorial();
tutorialWindow.center();
tutorialWindow.open();
@@ -247,6 +255,7 @@ qx.Class.define("osparc.dashboard.StudyBrowser", {
})
.catch(err => console.error(err))
.finally(() => {
+ this.__currentRequest = null;
this._loadingResourcesBtn.setFetching(false);
this._loadingResourcesBtn.setVisibility(this._resourcesContainer.getFlatList().nextRequest === null ? "excluded" : "visible");
this._moreResourcesRequired();
@@ -364,7 +373,7 @@ qx.Class.define("osparc.dashboard.StudyBrowser", {
this._resourcesContainer.setResourcesToList(this._resourcesList);
const cards = this._resourcesContainer.reloadCards("studies");
- this.__configureCards(cards);
+ this.__configureStudyCards(cards);
this.__addNewStudyButtons();
@@ -382,7 +391,7 @@ qx.Class.define("osparc.dashboard.StudyBrowser", {
_reloadNewCards: function() {
this._resourcesContainer.setResourcesToList(this._resourcesList);
const cards = this._resourcesContainer.reloadNewCards();
- this.__configureCards(cards);
+ this.__configureStudyCards(cards);
osparc.filter.UIFilterController.dispatch("searchBarFilter");
},
@@ -412,8 +421,15 @@ qx.Class.define("osparc.dashboard.StudyBrowser", {
const newWorkspaceCard = new osparc.dashboard.WorkspaceButtonNew();
newWorkspaceCard.setCardKey("new-workspace");
newWorkspaceCard.subscribeToFilterGroup("searchBarFilter");
- newWorkspaceCard.addListener("createWorkspace", () => this.__reloadWorkspaces());
- newWorkspaceCard.addListener("updateWorkspace", () => this.__reloadWorkspaces());
+ [
+ "createWorkspace",
+ "updateWorkspace"
+ ].forEach(e => {
+ newWorkspaceCard.addListener(e, () => {
+ this._resourceFilter.reloadWorkspaceButtons();
+ this.__reloadWorkspaces();
+ });
+ });
this._resourcesContainer.addNewWorkspaceCard(newWorkspaceCard);
},
@@ -427,15 +443,23 @@ qx.Class.define("osparc.dashboard.StudyBrowser", {
_deleteWorkspaceRequested: function(workspaceId) {
osparc.store.Workspaces.deleteWorkspace(workspaceId)
- .then(() => this.__reloadWorkspaceCards())
+ .then(() => {
+ this._resourceFilter.reloadWorkspaceButtons();
+ this.__reloadWorkspaces();
+ })
.catch(err => console.error(err));
},
// /WORKSPACES
// FOLDERS
- __applyCurrentFolderId: function(currentFolderId) {
+ __applyCurrentFolderId: function() {
if (osparc.utils.DisabledPlugins.isFoldersEnabled()) {
- osparc.store.Folders.getInstance().fetchFolders(currentFolderId)
+ const folderId = this.getCurrentFolderId();
+ const workspaceId = this.getCurrentWorkspaceId();
+ if (workspaceId === -1) {
+ return;
+ }
+ osparc.store.Folders.getInstance().fetchFolders(folderId, workspaceId)
.then(() => {
this._resourcesContainer.setResourcesToList([]);
this._resourcesList = [];
@@ -458,14 +482,21 @@ qx.Class.define("osparc.dashboard.StudyBrowser", {
newFolderCard.subscribeToFilterGroup("searchBarFilter");
newFolderCard.addListener("createFolder", e => {
const data = e.getData();
- osparc.store.Folders.getInstance().postFolder(data.name, data.description, currentFolder ? currentFolder.getFolderId() : null)
- .then(() => this.__reloadFolders())
- .catch(err => console.error(err));
- })
+ this.__createFolder(data);
+ }, this);
this._resourcesContainer.addNewFolderCard(newFolderCard);
}
},
+ __createFolder: function(data) {
+ const currentFolder = osparc.store.Folders.getInstance().getFolder(this.getCurrentFolderId())
+ const parentFolderId = currentFolder ? currentFolder.getFolderId() : null;
+ const currentWorkspaceId = this.getCurrentWorkspaceId();
+ osparc.store.Folders.getInstance().postFolder(data.name, parentFolderId, currentWorkspaceId)
+ .then(() => this.__reloadFolders())
+ .catch(err => console.error(err));
+ },
+
_folderSelected: function(folderId) {
this.setCurrentFolderId(folderId);
},
@@ -474,6 +505,48 @@ qx.Class.define("osparc.dashboard.StudyBrowser", {
this.__reloadFolders();
},
+ _moveFolderToFolderRequested: function(folderId) {
+ const moveFolderToFolder = new osparc.dashboard.MoveResourceToFolder(this.getCurrentFolderId(), this.getCurrentWorkspaceId());
+ const title = "Move to Folder";
+ const win = osparc.ui.window.Window.popUpInWindow(moveFolderToFolder, title, 350, 280);
+ moveFolderToFolder.addListener("moveToFolder", e => {
+ win.close();
+ const destFolderId = e.getData();
+ const params = {
+ url: {
+ folderId,
+ destFolderId,
+ }
+ };
+ osparc.data.Resources.fetch("folders", "moveToFolder", params)
+ .then(() => {
+ this.__reloadFolders()
+ })
+ .catch(err => console.error(err));
+ });
+ },
+
+ _moveFolderToWorkspaceRequested: function(folderId) {
+ const moveFolderToWorkspace = new osparc.dashboard.MoveResourceToWorkspace(this.getCurrentWorkspaceId());
+ const title = "Move to Workspace";
+ const win = osparc.ui.window.Window.popUpInWindow(moveFolderToWorkspace, title, 350, 280);
+ moveFolderToWorkspace.addListener("moveToWorkspace", e => {
+ win.close();
+ const destWorkspaceId = e.getData();
+ const params = {
+ url: {
+ folderId,
+ workspaceId: destWorkspaceId,
+ }
+ };
+ osparc.data.Resources.fetch("folders", "moveToWorkspace", params)
+ .then(() => {
+ this.__reloadFolders()
+ })
+ .catch(err => console.error(err));
+ });
+ },
+
_deleteFolderRequested: function(folderId) {
osparc.store.Folders.getInstance().deleteFolder(folderId)
.then(() => this.__reloadFolders())
@@ -481,7 +554,7 @@ qx.Class.define("osparc.dashboard.StudyBrowser", {
},
// /FOLDERS
- __configureCards: function(cards) {
+ __configureStudyCards: function(cards) {
cards.forEach(card => {
card.setMultiSelectionMode(this.getMultiSelection());
card.addListener("tap", e => {
@@ -559,7 +632,7 @@ qx.Class.define("osparc.dashboard.StudyBrowser", {
return null;
},
- __getNextRequest: function() {
+ __getNextStudiesRequest: function() {
const params = {
url: {
offset: 0,
@@ -576,14 +649,14 @@ qx.Class.define("osparc.dashboard.StudyBrowser", {
resolveWResponse: true
};
- const currentFolderId = this.getCurrentFolderId();
- params.url.folderId = currentFolderId;
+ params.url.workspaceId = this.getCurrentWorkspaceId();
+ params.url.folderId = this.getCurrentFolderId();
if (params.url.orderBy) {
- return osparc.data.Resources.fetch("studies", "getPageFolderSortBy", params, undefined, options);
+ return osparc.data.Resources.fetch("studies", "getPageSortBy", params, undefined, options);
} else if (params.url.search) {
- return osparc.data.Resources.fetch("studies", "getPageFolderSearch", params, undefined, options);
+ return osparc.data.Resources.fetch("studies", "getPageSearch", params, undefined, options);
}
- return osparc.data.Resources.fetch("studies", "getPageFolder", params, undefined, options);
+ return osparc.data.Resources.fetch("studies", "getPage", params, undefined, options);
},
__getTextFilteredNextRequest: function(text) {
@@ -603,9 +676,9 @@ qx.Class.define("osparc.dashboard.StudyBrowser", {
resolveWResponse: true
};
- const currentFolderId = this.getCurrentFolderId();
- params.url.folderId = currentFolderId;
- return osparc.data.Resources.fetch("studies", "getPageFolderSearch", params, undefined, options);
+ params.url.workspaceId = this.getCurrentWorkspaceId();
+ params.url.folderId = this.getCurrentFolderId();
+ return osparc.data.Resources.fetch("studies", "getPageSearch", params, undefined, options);
},
__getSortedByNextRequest: function() {
@@ -625,9 +698,9 @@ qx.Class.define("osparc.dashboard.StudyBrowser", {
resolveWResponse: true
};
- const currentFolderId = this.getCurrentFolderId();
- params.url.folderId = currentFolderId;
- return osparc.data.Resources.fetch("studies", "getPageFolderSortBy", params, undefined, options);
+ params.url.workspaceId = this.getCurrentWorkspaceId();
+ params.url.folderId = this.getCurrentFolderId();
+ return osparc.data.Resources.fetch("studies", "getPageSortBy", params, undefined, options);
},
invalidateStudies: function() {
@@ -774,8 +847,12 @@ qx.Class.define("osparc.dashboard.StudyBrowser", {
const containerHeader = this._resourcesContainer.getContainerHeader();
if (containerHeader) {
- this.bind("currentWorkspaceId", containerHeader, "currentWorkspaceId");
- containerHeader.bind("currentWorkspaceId", this, "currentWorkspaceId");
+ this.bind("currentWorkspaceId", containerHeader, "currentWorkspaceId", {
+ onUpdate: () => containerHeader.setCurrentFolderId(null)
+ });
+ containerHeader.bind("currentWorkspaceId", this, "currentWorkspaceId", {
+ onUpdate: () => this.setCurrentFolderId(null)
+ });
this.bind("currentFolderId", containerHeader, "currentFolderId");
containerHeader.bind("currentFolderId", this, "currentFolderId");
}
@@ -981,10 +1058,11 @@ qx.Class.define("osparc.dashboard.StudyBrowser", {
__newStudyBtnClicked: function(button) {
button.setValue(false);
- const minStudyData = osparc.data.model.Study.createMyNewStudyObject();
+ const minStudyData = osparc.data.model.Study.createMinStudyObject();
const title = osparc.utils.Utils.getUniqueStudyName(minStudyData.name, this._resourcesList);
minStudyData["name"] = title;
- minStudyData["description"] = "";
+ minStudyData["workspaceId"] = this.getCurrentWorkspaceId();
+ minStudyData["folderId"] = this.getCurrentFolderId();
this._showLoadingPage(this.tr("Creating ") + (minStudyData.name || osparc.product.Utils.getStudyAlias()));
const params = {
data: minStudyData
@@ -1004,7 +1082,11 @@ qx.Class.define("osparc.dashboard.StudyBrowser", {
const title = osparc.utils.Utils.getUniqueStudyName(newStudyName, this._resourcesList);
templateCopyData.name = title;
this._showLoadingPage(this.tr("Creating ") + (newStudyName || osparc.product.Utils.getStudyAlias()));
- osparc.study.Utils.createStudyFromTemplate(templateCopyData, this._loadingPage)
+ const contextProps = {
+ workspaceId: this.getCurrentWorkspaceId(),
+ folderId: this.getCurrentFolderId(),
+ };
+ osparc.study.Utils.createStudyFromTemplate(templateCopyData, this._loadingPage, contextProps)
.then(studyId => this.__startStudyAfterCreating(studyId))
.catch(err => {
this._hideLoadingPage();
@@ -1016,7 +1098,11 @@ qx.Class.define("osparc.dashboard.StudyBrowser", {
__newStudyFromServiceBtnClicked: function(button, key, version, newStudyLabel) {
button.setValue(false);
this._showLoadingPage(this.tr("Creating ") + osparc.product.Utils.getStudyAlias());
- osparc.study.Utils.createStudyFromService(key, version, this._resourcesList, newStudyLabel)
+ const contextProps = {
+ workspaceId: this.getCurrentWorkspaceId(),
+ folderId: this.getCurrentFolderId(),
+ };
+ osparc.study.Utils.createStudyFromService(key, version, this._resourcesList, newStudyLabel, contextProps)
.then(studyId => this.__startStudyAfterCreating(studyId))
.catch(err => {
this._hideLoadingPage();
@@ -1026,9 +1112,6 @@ qx.Class.define("osparc.dashboard.StudyBrowser", {
},
__startStudyAfterCreating: function(studyId) {
- if (this.getCurrentFolderId()) {
- this.__moveStudyToFolder(studyId, this.getCurrentFolderId());
- }
const openCB = () => this._hideLoadingPage();
const cancelCB = () => {
this._hideLoadingPage();
@@ -1043,16 +1126,6 @@ qx.Class.define("osparc.dashboard.StudyBrowser", {
this._startStudyById(studyId, openCB, cancelCB, isStudyCreation);
},
- __moveStudyToFolder: function(studyId, folderId) {
- const params = {
- url: {
- studyId,
- folderId
- }
- };
- return osparc.data.Resources.fetch("studies", "moveToFolder", params);
- },
-
_updateStudyData: function(studyData) {
studyData["resourceType"] = "study";
const studies = this._resourcesList;
@@ -1106,7 +1179,8 @@ qx.Class.define("osparc.dashboard.StudyBrowser", {
menu.addSeparator();
- if (writeAccess) {
+ // Access Rights are set at workspace level)
+ if (writeAccess && this.getCurrentWorkspaceId() === null) {
const shareButton = this._getShareMenuButton(card);
if (shareButton) {
menu.add(shareButton);
@@ -1129,10 +1203,17 @@ qx.Class.define("osparc.dashboard.StudyBrowser", {
}
if (writeAccess && osparc.utils.DisabledPlugins.isFoldersEnabled()) {
- const moveToFolderButton = this.__getMoveToFolderMenuButton(studyData);
+ menu.addSeparator();
+
+ const moveToFolderButton = this.__getMoveStudyToFolderMenuButton(studyData);
if (moveToFolderButton) {
menu.add(moveToFolderButton);
}
+
+ const moveToWorkspaceButton = this.__getMoveStudyToWorkspaceMenuButton(studyData);
+ if (moveToWorkspaceButton) {
+ menu.add(moveToWorkspaceButton);
+ }
}
if (deleteAccess) {
@@ -1217,35 +1298,68 @@ qx.Class.define("osparc.dashboard.StudyBrowser", {
return studyBillingSettingsButton;
},
- __getMoveToFolderMenuButton: function(studyData) {
- const text = osparc.utils.Utils.capitalize(this.tr("Move to Folder..."));
+ __getMoveStudyToFolderMenuButton: function(studyData) {
+ const text = this.tr("Move to Folder...");
const moveToFolderButton = new qx.ui.menu.Button(text, "@FontAwesome5Solid/folder/12");
moveToFolderButton["moveToFolderButton"] = true;
moveToFolderButton.addListener("tap", () => {
- if (Object.keys(studyData["accessRights"]).length > 1) {
- osparc.FlashMessenger.getInstance().logAs(this.tr("Shared projects can't be moved yet"), "WARNING");
- } else {
- const title = this.tr("Move") + " " + studyData["name"];
- const moveStudyToFolder = new osparc.dashboard.MoveStudyToFolder(studyData, this.getCurrentFolderId());
- const win = osparc.ui.window.Window.popUpInWindow(moveStudyToFolder, title, 350, 280);
- moveStudyToFolder.addListener("moveToFolder", e => {
- win.close();
- const folderId = e.getData();
- this.__moveStudyToFolder(studyData["uuid"], folderId)
- .then(() => {
- this.__removeFromStudyList(studyData["uuid"]);
- })
- .catch(err => {
- console.error(err);
- osparc.FlashMessenger.logAs(err.message, "ERROR");
- });
- }, this);
- moveStudyToFolder.addListener("cancel", () => win.close());
- }
+ const title = this.tr("Move") + " " + studyData["name"];
+ const moveStudyToFolder = new osparc.dashboard.MoveResourceToFolder(this.getCurrentFolderId(), this.getCurrentWorkspaceId());
+ const win = osparc.ui.window.Window.popUpInWindow(moveStudyToFolder, title, 350, 280);
+ moveStudyToFolder.addListener("moveToFolder", e => {
+ win.close();
+ const destFolderId = e.getData();
+ const params = {
+ url: {
+ studyId: studyData["uuid"],
+ folderId: destFolderId,
+ }
+ };
+ osparc.data.Resources.fetch("studies", "moveToFolder", params)
+ .then(() => {
+ this.__removeFromStudyList(studyData["uuid"]);
+ })
+ .catch(err => {
+ console.error(err);
+ osparc.FlashMessenger.logAs(err.message, "ERROR");
+ });
+ }, this);
+ moveStudyToFolder.addListener("cancel", () => win.close());
}, this);
return moveToFolderButton;
},
+ __getMoveStudyToWorkspaceMenuButton: function(studyData) {
+ const text = this.tr("Move to Workspace...");
+ const moveToWorkspaceButton = new qx.ui.menu.Button(text, osparc.store.Workspaces.iconPath(14));
+ moveToWorkspaceButton["moveToWorkspaceButton"] = true;
+ moveToWorkspaceButton.addListener("tap", () => {
+ const title = this.tr("Move") + " " + studyData["name"];
+ const moveStudyToWorkspace = new osparc.dashboard.MoveResourceToWorkspace(this.getCurrentFolderId());
+ const win = osparc.ui.window.Window.popUpInWindow(moveStudyToWorkspace, title, 350, 280);
+ moveStudyToWorkspace.addListener("moveToWorkspace", e => {
+ win.close();
+ const destWorkspaceId = e.getData();
+ const params = {
+ url: {
+ studyId: studyData["uuid"],
+ workspaceId: destWorkspaceId,
+ }
+ };
+ osparc.data.Resources.fetch("studies", "moveToWorkspace", params)
+ .then(() => {
+ this.__removeFromStudyList(studyData["uuid"]);
+ })
+ .catch(err => {
+ console.error(err);
+ osparc.FlashMessenger.logAs(err.message, "ERROR");
+ });
+ }, this);
+ moveStudyToWorkspace.addListener("cancel", () => win.close());
+ }, this);
+ return moveToWorkspaceButton;
+ },
+
__getDuplicateMenuButton: function(studyData) {
const duplicateButton = new qx.ui.menu.Button(this.tr("Duplicate"), "@FontAwesome5Solid/copy/12");
duplicateButton["duplicateButton"] = true;
diff --git a/services/static-webserver/client/source/class/osparc/dashboard/WorkspaceButtonBase.js b/services/static-webserver/client/source/class/osparc/dashboard/WorkspaceButtonBase.js
index fbcf92b3bf7..844004de698 100644
--- a/services/static-webserver/client/source/class/osparc/dashboard/WorkspaceButtonBase.js
+++ b/services/static-webserver/client/source/class/osparc/dashboard/WorkspaceButtonBase.js
@@ -192,14 +192,18 @@ qx.Class.define("osparc.dashboard.WorkspaceButtonBase", {
// overridden
_applyIcon: function(value) {
+ const image = this.getChildControl("icon").getChildControl("image");
if (
value.includes("@FontAwesome5Solid/") ||
value.includes("@MaterialIcons/")
) {
+ this.getContentElement().setStyles({
+ "background-image": "none",
+ });
value += this.self().ICON_SIZE;
- const image = this.getChildControl("icon").getChildControl("image");
image.set({
- source: value
+ source: value,
+ visibility: "visible",
});
} else {
this.getContentElement().setStyles({
@@ -209,6 +213,9 @@ qx.Class.define("osparc.dashboard.WorkspaceButtonBase", {
"background-position": "center center",
"background-origin": "border-box"
});
+ image.set({
+ visibility: "excluded",
+ });
}
},
diff --git a/services/static-webserver/client/source/class/osparc/dashboard/WorkspaceButtonItem.js b/services/static-webserver/client/source/class/osparc/dashboard/WorkspaceButtonItem.js
index 176d2775f46..2b49a333b8a 100644
--- a/services/static-webserver/client/source/class/osparc/dashboard/WorkspaceButtonItem.js
+++ b/services/static-webserver/client/source/class/osparc/dashboard/WorkspaceButtonItem.js
@@ -85,10 +85,10 @@ qx.Class.define("osparc.dashboard.WorkspaceButtonItem", {
apply: "__applyAccessRights"
},
- lastModified: {
+ modifiedAt: {
check: "Date",
nullable: true,
- apply: "__applyLastModified"
+ apply: "__applyModifiedAt"
}
},
@@ -157,7 +157,7 @@ qx.Class.define("osparc.dashboard.WorkspaceButtonItem", {
converter: thumbnail => thumbnail ? thumbnail : osparc.store.Workspaces.iconPath(-1)
});
workspace.bind("accessRights", this, "accessRights");
- workspace.bind("lastModified", this, "lastModified");
+ workspace.bind("modifiedAt", this, "modifiedAt");
workspace.bind("myAccessRights", this, "myAccessRights");
},
@@ -180,29 +180,28 @@ qx.Class.define("osparc.dashboard.WorkspaceButtonItem", {
position: "bottom-right"
});
- const editButton = new qx.ui.menu.Button(this.tr("Rename..."), "@FontAwesome5Solid/pencil-alt/12");
+ const editButton = new qx.ui.menu.Button(this.tr("Edit..."), "@FontAwesome5Solid/pencil-alt/12");
editButton.addListener("execute", () => {
const workspace = this.getWorkspace();
const newWorkspace = false;
const workspaceEditor = new osparc.editor.WorkspaceEditor(newWorkspace).set({
label: workspace.getName(),
- description: workspace.getDescription()
+ description: workspace.getDescription(),
+ thumbnail: workspace.getThumbnail(),
});
const title = this.tr("Edit Workspace");
const win = osparc.ui.window.Window.popUpInWindow(workspaceEditor, title, 300, 200);
workspaceEditor.addListener("updateWorkspace", () => {
const newName = workspaceEditor.getLabel();
const newDescription = workspaceEditor.getDescription();
+ const newThumbnail = workspaceEditor.getThumbnail();
const updateData = {
"name": newName,
- "description": newDescription
+ "description": newDescription,
+ "thumbnail": newThumbnail,
};
- osparc.data.model.Workspace.putWorkspace(this.getWorkspaceId(), updateData)
+ osparc.store.Workspaces.putWorkspace(this.getWorkspaceId(), updateData)
.then(() => {
- workspace.set({
- name: newName,
- description: newDescription
- });
this.fireDataEvent("workspaceUpdated", workspace.getWorkspaceId());
})
.catch(err => console.error(err));
@@ -238,7 +237,7 @@ qx.Class.define("osparc.dashboard.WorkspaceButtonItem", {
}
},
- __applyLastModified: function(value) {
+ __applyModifiedAt: function(value) {
const label = this.getChildControl("modified-text");
label.setValue(osparc.utils.Utils.formatDateAndTime(value));
},
diff --git a/services/static-webserver/client/source/class/osparc/dashboard/WorkspaceTreeItem.js b/services/static-webserver/client/source/class/osparc/dashboard/WorkspaceTreeItem.js
new file mode 100644
index 00000000000..f6959bb446b
--- /dev/null
+++ b/services/static-webserver/client/source/class/osparc/dashboard/WorkspaceTreeItem.js
@@ -0,0 +1,41 @@
+/* ************************************************************************
+
+ osparc - the simcore frontend
+
+ https://osparc.io
+
+ Copyright:
+ 2024 IT'IS Foundation, https://itis.swiss
+
+ License:
+ MIT: https://opensource.org/licenses/MIT
+
+ Authors:
+ * Odei Maiz (odeimaiz)
+
+************************************************************************ */
+
+qx.Class.define("osparc.dashboard.WorkspaceTreeItem", {
+ extend: qx.ui.tree.VirtualTreeItem,
+
+ members: {
+ _addWidgets: function() {
+ this.addSpacer();
+ // this.addOpenButton();
+ const openButton = this.getChildControl("open");
+ openButton.addListener("changeOpen", () => {
+ console.log("changeOpen", this);
+ }, this);
+ openButton.addListener("changeVisibility", e => {
+ // console.log("changeVisibility", this.getLabel() + e.getData(), this);
+ openButton.show();
+ }, this);
+ this._add(openButton);
+ this.addIcon();
+ const label = this.getChildControl("label");
+ this._add(label, {
+ flex: 1
+ });
+ }
+ }
+});
diff --git a/services/static-webserver/client/source/class/osparc/dashboard/WorkspacesTree.js b/services/static-webserver/client/source/class/osparc/dashboard/WorkspacesTree.js
new file mode 100644
index 00000000000..0c0c2ce078e
--- /dev/null
+++ b/services/static-webserver/client/source/class/osparc/dashboard/WorkspacesTree.js
@@ -0,0 +1,127 @@
+/* ************************************************************************
+
+ osparc - the simcore frontend
+
+ https://osparc.io
+
+ Copyright:
+ 2024 IT'IS Foundation, https://itis.swiss
+
+ License:
+ MIT: https://opensource.org/licenses/MIT
+
+ Authors:
+ * Odei Maiz (odeimaiz)
+
+************************************************************************ */
+
+qx.Class.define("osparc.dashboard.WorkspacesTree", {
+ extend: qx.ui.tree.VirtualTree,
+
+ construct: function() {
+ const rootLabel = "Root";
+ const rootWorkspace = this.self().createNewEntry(rootLabel, null);
+ const root = qx.data.marshal.Json.createModel(rootWorkspace, true);
+ this.__fetchChildren(root);
+
+ this.base(arguments, root, "label", "children");
+
+ this.set({
+ openMode: "dbltap",
+ decorator: "no-border",
+ font: "text-14",
+ showLeafs: true,
+ paddingLeft: -10,
+ hideRoot: true
+ });
+
+ this.__initTree();
+ },
+
+ events: {
+ "selectionChanged": "qx.event.type.Event" // tap
+ },
+
+ statics: {
+ createNewEntry: function(label, workspaceId) {
+ return {
+ label,
+ workspaceId,
+ children: [
+ this.self().getLoadingData()
+ ],
+ loaded: false,
+ };
+ },
+
+ getLoadingData: function() {
+ return {
+ workspaceId: -1,
+ label: "Loading...",
+ children: [],
+ icon: "@FontAwesome5Solid/circle-notch/12",
+ loaded: false,
+ };
+ },
+
+ addLoadingChild: function(parentModel) {
+ const loadingModel = qx.data.marshal.Json.createModel(this.self().getLoadingData(), true);
+ parentModel.getChildren().append(loadingModel);
+ },
+
+ removeLoadingChild: function(parent) {
+ for (let i = parent.getChildren().getLength() - 1; i >= 0; i--) {
+ if (parent.getChildren().toArray()[i].getLabel() === "Loading...") {
+ parent.getChildren().splice(i, 1);
+ }
+ }
+ }
+ },
+
+ members: {
+ __currentWorkspaceId:null,
+
+ __initTree: function() {
+ this.setDelegate({
+ createItem: () => new osparc.dashboard.WorkspaceTreeItem(),
+ bindItem: (c, item, id) => {
+ c.bindDefaultProperties(item, id);
+ c.bindProperty("workspaceId", "model", null, item, id);
+ },
+ configureItem: item => {
+ item.addListener("tap", () => this.fireDataEvent("selectionChanged", item.getModel()), this);
+ },
+ sorter: (a, b) => {
+ const aLabel = a.getLabel();
+ if (aLabel === -1) {
+ return 1;
+ }
+ const bLabel = b.getLabel();
+ if (bLabel === -1) {
+ return -1;
+ }
+ return aLabel - bLabel;
+ }
+ });
+ },
+
+ __fetchChildren: function(parentModel) {
+ parentModel.setLoaded(true);
+
+ const myWorkspaceData = this.self().createNewEntry("My Workspace", null);
+ const myWorkspaceModel = qx.data.marshal.Json.createModel(myWorkspaceData, true);
+ parentModel.getChildren().append(myWorkspaceModel);
+
+ osparc.store.Workspaces.fetchWorkspaces()
+ .then(workspaces => {
+ this.self().removeLoadingChild(parentModel);
+ workspaces.forEach(workspace => {
+ const workspaceData = this.self().createNewEntry(workspace.getName(), workspace.getWorkspaceId());
+ const workspaceModel = qx.data.marshal.Json.createModel(workspaceData, true);
+ parentModel.getChildren().append(workspaceModel);
+ });
+ })
+ .catch(console.error);
+ }
+ }
+});
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 098d3239bfa..4516598e2dd 100644
--- a/services/static-webserver/client/source/class/osparc/data/Resources.js
+++ b/services/static-webserver/client/source/class/osparc/data/Resources.js
@@ -119,19 +119,19 @@ qx.Class.define("osparc.data.Resources", {
method: "GET",
url: statics.API + "/projects?type=user"
},
- getPageFolder: {
+ getPage: {
method: "GET",
- url: statics.API + "/projects?type=user&offset={offset}&limit={limit}&folder_id={folderId}"
+ url: statics.API + "/projects?type=user&offset={offset}&limit={limit}&workspace_id={workspaceId}&folder_id={folderId}"
},
- getPageFolderSearch: {
+ getPageSearch: {
useCache: false,
method: "GET",
- url: statics.API + "/projects?type=user&offset={offset}&limit={limit}&folder_id={folderId}&search={text}"
+ url: statics.API + "/projects?type=user&offset={offset}&limit={limit}&workspace_id={workspaceId}&folder_id={folderId}&search={text}"
},
- getPageFolderSortBy: {
+ getPageSortBy: {
useCache: false,
method: "GET",
- url: statics.API + "/projects?type=user&offset={offset}&limit={limit}&folder_id={folderId}&order_by={orderBy}"
+ url: statics.API + "/projects?type=user&offset={offset}&limit={limit}&workspace_id={workspaceId}&folder_id={folderId}&order_by={orderBy}"
},
getOne: {
useCache: false,
@@ -276,7 +276,11 @@ qx.Class.define("osparc.data.Resources", {
moveToFolder: {
method: "PUT",
url: statics.API + "/projects/{studyId}/folders/{folderId}"
- }
+ },
+ moveToWorkspace: {
+ method: "PUT",
+ url: statics.API + "/projects/{studyId}/workspaces/{workspaceId}"
+ },
}
},
"studyComments": {
@@ -299,7 +303,7 @@ qx.Class.define("osparc.data.Resources", {
endpoints: {
getPage: {
method: "GET",
- url: statics.API + "/folders?folder_id={folderId}&offset={offset}&limit={limit}"
+ url: statics.API + "/folders?workspace_id={workspaceId}&folder_id={folderId}&offset={offset}&limit={limit}"
},
getOne: {
method: "GET",
@@ -316,14 +320,22 @@ qx.Class.define("osparc.data.Resources", {
delete: {
method: "DELETE",
url: statics.API + "/folders/{folderId}"
- }
+ },
+ moveToFolder: {
+ method: "PUT",
+ url: statics.API + "/folders/{folderId}/folders/{destFolderId}"
+ },
+ moveToWorkspace: {
+ method: "PUT",
+ url: statics.API + "/folders/{folderId}/folders/{workspaceId}"
+ },
}
},
"workspaces": {
endpoints: {
getPage: {
method: "GET",
- url: statics.API + "/workspaces?workspace_id={workspaceId}&offset={offset}&limit={limit}"
+ url: statics.API + "/workspaces?&offset={offset}&limit={limit}"
},
getOne: {
method: "GET",
diff --git a/services/static-webserver/client/source/class/osparc/data/model/Folder.js b/services/static-webserver/client/source/class/osparc/data/model/Folder.js
index a3e1eb7ca90..d9d2b517212 100644
--- a/services/static-webserver/client/source/class/osparc/data/model/Folder.js
+++ b/services/static-webserver/client/source/class/osparc/data/model/Folder.js
@@ -32,9 +32,7 @@ qx.Class.define("osparc.data.model.Folder", {
folderId: folderData.folderId,
parentId: folderData.parentFolderId,
name: folderData.name,
- description: folderData.description,
myAccessRights: folderData.myAccessRights,
- accessRights: folderData.accessRights,
owner: folderData.owner,
createdAt: new Date(folderData.createdAt),
lastModified: new Date(folderData.modifiedAt),
@@ -63,13 +61,6 @@ qx.Class.define("osparc.data.model.Folder", {
event: "changeName"
},
- description: {
- check: "String",
- nullable: true,
- init: null,
- event: "changeDescription"
- },
-
myAccessRights: {
check: "Object",
nullable: false,
@@ -77,13 +68,6 @@ qx.Class.define("osparc.data.model.Folder", {
event: "changeMyAccessRights"
},
- accessRights: {
- check: "Object",
- nullable: false,
- init: null,
- event: "changeAccessRights"
- },
-
owner: {
check: "Number",
nullable: true,
diff --git a/services/static-webserver/client/source/class/osparc/data/model/Study.js b/services/static-webserver/client/source/class/osparc/data/model/Study.js
index 8fd40a67a28..0df98435304 100644
--- a/services/static-webserver/client/source/class/osparc/data/model/Study.js
+++ b/services/static-webserver/client/source/class/osparc/data/model/Study.js
@@ -214,7 +214,7 @@ qx.Class.define("osparc.data.model.Study", {
"workbench"
],
- createMyNewStudyObject: function() {
+ createMinStudyObject: function() {
let myNewStudyObject = {};
const props = qx.util.PropertyUtil.getProperties(osparc.data.model.Study);
for (let key in props) {
diff --git a/services/static-webserver/client/source/class/osparc/data/model/Workspace.js b/services/static-webserver/client/source/class/osparc/data/model/Workspace.js
index ea4c324e9aa..56023d1eb4e 100644
--- a/services/static-webserver/client/source/class/osparc/data/model/Workspace.js
+++ b/services/static-webserver/client/source/class/osparc/data/model/Workspace.js
@@ -36,7 +36,7 @@ qx.Class.define("osparc.data.model.Workspace", {
myAccessRights: workspaceData.myAccessRights,
accessRights: workspaceData.accessRights,
createdAt: new Date(workspaceData.createdAt),
- lastModified: new Date(workspaceData.lastModified),
+ modifiedAt: new Date(workspaceData.modifiedAt),
});
},
@@ -90,19 +90,15 @@ qx.Class.define("osparc.data.model.Workspace", {
event: "changeCreatedAt"
},
- lastModified: {
+ modifiedAt: {
check: "Date",
nullable: true,
init: null,
- event: "changeLastModified"
+ event: "changeModifiedAt"
}
},
statics: {
- putWorkspace: function(workspaceId, propKey, value) {
- return osparc.store.Workspaces.putWorkspace(workspaceId, propKey, value);
- },
-
getProperties: function() {
return Object.keys(qx.util.PropertyUtil.getProperties(osparc.data.model.Workspace));
}
diff --git a/services/static-webserver/client/source/class/osparc/desktop/organizations/OrganizationsList.js b/services/static-webserver/client/source/class/osparc/desktop/organizations/OrganizationsList.js
index 611f1bd77bc..935c9cfc35b 100644
--- a/services/static-webserver/client/source/class/osparc/desktop/organizations/OrganizationsList.js
+++ b/services/static-webserver/client/source/class/osparc/desktop/organizations/OrganizationsList.js
@@ -25,7 +25,7 @@ qx.Class.define("osparc.desktop.organizations.OrganizationsList", {
const studiesLabel = osparc.product.Utils.getStudyAlias({plural: true});
const msg = this.tr("\
- An organization is a group of users who can share ") + studiesLabel + this.tr(".
\
+ An organization is a group of users who can share ") + studiesLabel + this.tr(" and other resources.
\
Here you can see the list of organizations you belong to, create new organizations, \
or manage the membership by setting up the access rights of each member in the organization \
if you are a manager or administrator.");
diff --git a/services/static-webserver/client/source/class/osparc/editor/FolderEditor.js b/services/static-webserver/client/source/class/osparc/editor/FolderEditor.js
index 5080b96b9be..1948026e352 100644
--- a/services/static-webserver/client/source/class/osparc/editor/FolderEditor.js
+++ b/services/static-webserver/client/source/class/osparc/editor/FolderEditor.js
@@ -27,32 +27,17 @@ qx.Class.define("osparc.editor.FolderEditor", {
const title = this.getChildControl("title");
title.setRequired(true);
manager.add(title);
- this.getChildControl("description");
newFolder ? this.getChildControl("create") : this.getChildControl("save");
this.addListener("appear", this.__onAppear, this);
},
properties: {
- gid: {
- check: "Number",
- init: 0,
- nullable: false,
- event: "changeGid"
- },
-
label: {
check: "String",
init: "",
nullable: false,
event: "changeLabel"
- },
-
- description: {
- check: "String",
- init: "",
- nullable: false,
- event: "changeDescription"
}
},
@@ -78,19 +63,6 @@ qx.Class.define("osparc.editor.FolderEditor", {
this._add(control);
break;
}
- case "description": {
- control = new qx.ui.form.TextArea().set({
- font: "text-14",
- placeholder: this.tr("Description"),
- autoSize: true,
- minHeight: 70,
- maxHeight: 140
- });
- this.bind("description", control, "value");
- control.bind("value", this, "description");
- this._add(control);
- break;
- }
case "create": {
const buttons = this.getChildControl("buttonsLayout");
control = new osparc.ui.form.FetchButton(this.tr("Create")).set({
diff --git a/services/static-webserver/client/source/class/osparc/filter/CollaboratorToggleButton.js b/services/static-webserver/client/source/class/osparc/filter/CollaboratorToggleButton.js
index 90ccbd2171a..31d3aef3512 100644
--- a/services/static-webserver/client/source/class/osparc/filter/CollaboratorToggleButton.js
+++ b/services/static-webserver/client/source/class/osparc/filter/CollaboratorToggleButton.js
@@ -26,7 +26,13 @@ qx.Class.define("osparc.filter.CollaboratorToggleButton", {
let label = null;
if (collaborator["first_name"]) {
// user
- label = `${collaborator["first_name"]} ${"last_name" in collaborator && collaborator["last_name"] != null ? collaborator["last_name"] : ""}`;
+ label = collaborator["first_name"];
+ if (collaborator["last_name"]) {
+ label += ` ${collaborator["last_name"]}`;
+ }
+ if (collaborator["login"]) {
+ label += ` (${collaborator["login"]})`;
+ }
} else if ("login" in collaborator) {
label = collaborator["login"];
} else {
@@ -35,7 +41,7 @@ qx.Class.define("osparc.filter.CollaboratorToggleButton", {
}
this.setLabel(label);
- if ("login" in collaborator) {
+ if (collaborator["login"]) {
this.setToolTipText(collaborator["login"]);
}
diff --git a/services/static-webserver/client/source/class/osparc/share/Collaborators.js b/services/static-webserver/client/source/class/osparc/share/Collaborators.js
index c315c7d26d3..9c282f858ed 100644
--- a/services/static-webserver/client/source/class/osparc/share/Collaborators.js
+++ b/services/static-webserver/client/source/class/osparc/share/Collaborators.js
@@ -189,7 +189,11 @@ qx.Class.define("osparc.share.Collaborators", {
return control || this.base(arguments, id);
},
- __amIOwner: function() {
+ __canIChangePermissions: function() {
+ if (this._resourceType === "study" && this._serializedDataCopy["workspaceId"]) {
+ // Access Rights are set at workspace level
+ return false;
+ }
let fullOptions = false;
switch (this._resourceType) {
case "study":
@@ -223,7 +227,7 @@ qx.Class.define("osparc.share.Collaborators", {
},
__buildLayout: function() {
- if (this.__amIOwner()) {
+ if (this.__canIChangePermissions()) {
this.__addCollaborators = this._createChildControlImpl("add-collaborator");
}
this._createChildControlImpl("collaborators-list");
@@ -382,7 +386,7 @@ qx.Class.define("osparc.share.Collaborators", {
];
const accessRights = this._serializedDataCopy["accessRights"];
const collaboratorsList = [];
- const showOptions = this.__amIOwner();
+ const showOptions = this.__canIChangePermissions();
Object.keys(accessRights).forEach(gid => {
if (Object.prototype.hasOwnProperty.call(this.__collaborators, gid)) {
const collab = this.__collaborators[gid];
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 b8c8752c6eb..148d8df6f14 100644
--- a/services/static-webserver/client/source/class/osparc/share/NewCollaboratorsManager.js
+++ b/services/static-webserver/client/source/class/osparc/share/NewCollaboratorsManager.js
@@ -18,7 +18,7 @@ qx.Class.define("osparc.share.NewCollaboratorsManager", {
showMaximize: false,
autoDestroy: true,
modal: true,
- width: 262,
+ width: 350,
maxHeight: 500,
clickAwayClose: true
});
@@ -43,7 +43,10 @@ qx.Class.define("osparc.share.NewCollaboratorsManager", {
members: {
__resourceData: null,
__showOrganizations: null,
+ __introLabel: null,
+ __textFilter: null,
__collabButtonsContainer: null,
+ __orgsButton: null,
__shareButton: null,
__selectedCollaborators: null,
__visibleCollaborators: null,
@@ -53,7 +56,16 @@ qx.Class.define("osparc.share.NewCollaboratorsManager", {
},
__renderLayout: function() {
- const filter = new osparc.filter.TextFilter("name", "collaboratorsManager").set({
+ const introText = this.tr("In order to start Sharing with other members, you first need to belong to an Organization.");
+ const introLabel = this.__introLabel = new qx.ui.basic.Label(introText).set({
+ rich: true,
+ wrap: true,
+ visibility: "excluded",
+ padding: 8
+ });
+ this.add(introLabel);
+
+ const filter = this.__textFilter = new osparc.filter.TextFilter("name", "collaboratorsManager").set({
allowStretchX: true,
margin: [0, 10, 5, 10]
});
@@ -70,8 +82,15 @@ qx.Class.define("osparc.share.NewCollaboratorsManager", {
const buttons = new qx.ui.container.Composite(new qx.ui.layout.HBox().set({
alignX: "right"
}));
+ const orgsButton = this.__orgsButton = new qx.ui.form.Button(this.tr("Check Organizations...")).set({
+ appearance: "form-button",
+ visibility: "excluded",
+ });
+ orgsButton.addListener("execute", () => osparc.desktop.organizations.OrganizationsWindow.openWindow(), this);
+ buttons.add(orgsButton);
const shareButton = this.__shareButton = new osparc.ui.form.FetchButton(this.tr("Share")).set({
- appearance: "form-button"
+ appearance: "form-button",
+ enabled: false,
});
shareButton.addListener("execute", () => this.__shareClicked(), this);
buttons.add(shareButton);
@@ -95,6 +114,15 @@ qx.Class.define("osparc.share.NewCollaboratorsManager", {
osparc.store.Store.getInstance().getPotentialCollaborators(false, includeProductEveryone)
.then(potentialCollaborators => {
this.__visibleCollaborators = potentialCollaborators;
+ const anyCollaborator = Object.keys(potentialCollaborators).length;
+ // tell the user that belonging to an organization is required to start sharing
+ this.__introLabel.setVisibility(anyCollaborator ? "excluded" : "visible");
+ this.__orgsButton.setVisibility(anyCollaborator ? "excluded" : "visible");
+
+ // or start sharing
+ this.__textFilter.setVisibility(anyCollaborator ? "visible" : "excluded");
+ this.__collabButtonsContainer.setVisibility(anyCollaborator ? "visible" : "excluded");
+ this.__shareButton.setVisibility(anyCollaborator ? "visible" : "excluded");
this.__addEditors();
});
},
@@ -108,6 +136,7 @@ qx.Class.define("osparc.share.NewCollaboratorsManager", {
} else {
this.__selectedCollaborators.remove(collaborator.gid);
}
+ this.__shareButton.setEnabled(Boolean(this.__selectedCollaborators.length));
}, this);
collaboratorButton.subscribeToFilterGroup("collaboratorsManager");
return collaboratorButton;
@@ -155,6 +184,9 @@ qx.Class.define("osparc.share.NewCollaboratorsManager", {
});
},
+ __openOrganization: function() {
+ },
+
__shareClicked: function() {
this.__collabButtonsContainer.setEnabled(false);
this.__shareButton.setFetching(true);
diff --git a/services/static-webserver/client/source/class/osparc/store/Folders.js b/services/static-webserver/client/source/class/osparc/store/Folders.js
index 5b3459852b9..351e090f6f2 100644
--- a/services/static-webserver/client/source/class/osparc/store/Folders.js
+++ b/services/static-webserver/client/source/class/osparc/store/Folders.js
@@ -28,7 +28,7 @@ qx.Class.define("osparc.store.Folders", {
members: {
foldersCached: null,
- fetchFolders: function(folderId = null) {
+ fetchFolders: function(folderId = null, workspaceId = null) {
if (osparc.auth.Data.getInstance().isGuest()) {
return new Promise(resolve => {
resolve([]);
@@ -37,7 +37,8 @@ qx.Class.define("osparc.store.Folders", {
const params = {
"url": {
- folderId
+ workspaceId,
+ folderId,
}
};
return osparc.data.Resources.getInstance().getAllPages("folders", params)
@@ -52,11 +53,11 @@ qx.Class.define("osparc.store.Folders", {
});
},
- postFolder: function(name, description, parentId = null) {
+ postFolder: function(name, parentFolderId = null, workspaceId = null) {
const newFolderData = {
- parentFolderId: parentId,
- name: name,
- description: description || "",
+ name,
+ parentFolderId,
+ workspaceId,
};
const params = {
data: newFolderData
diff --git a/services/static-webserver/client/source/class/osparc/store/Workspaces.js b/services/static-webserver/client/source/class/osparc/store/Workspaces.js
index 6d0664abb0a..839670ffb24 100644
--- a/services/static-webserver/client/source/class/osparc/store/Workspaces.js
+++ b/services/static-webserver/client/source/class/osparc/store/Workspaces.js
@@ -29,94 +29,13 @@ qx.Class.define("osparc.store.Workspaces", {
return source+iconsSize;
},
- FAKE_WORKSPACES: [{
- workspaceId: 1,
- name: "Workspace 1",
- description: "Workspace 1 desc",
- thumbnail: "https://images.ctfassets.net/hrltx12pl8hq/01rJn4TormMsGQs1ZRIpzX/16a1cae2440420d0fd0a7a9a006f2dcb/Artboard_Copy_231.jpg?fit=fill&w=600&h=600",
- myAccessRights: {
- read: true,
- write: true,
- delete: true,
- },
- accessRights: {
- 3: {
- read: true,
- write: true,
- delete: true,
- },
- 5: {
- read: true,
- write: true,
- delete: false,
- },
- 9: {
- read: true,
- write: false,
- delete: false,
- },
- },
- createdAt: "2024-03-04 15:59:51.579217",
- lastModified: "2024-03-05 15:18:21.515403",
- }, {
- workspaceId: 2,
- name: "Workspace 2",
- description: "Workspace 2 desc",
- thumbnail: "",
- myAccessRights: {
- read: true,
- write: true,
- delete: false,
- },
- accessRights: {
- 3: {
- read: true,
- write: true,
- delete: false,
- },
- 5: {
- read: true,
- write: true,
- delete: true,
- },
- 9: {
- read: true,
- write: false,
- delete: false,
- },
- },
- createdAt: "2024-03-05 15:18:21.515403",
- lastModified: "2024-04-24 12:03:05.15249",
- }, {
- workspaceId: 3,
- name: "Workspace 3",
- description: "Workspace 3 desc",
- thumbnail: "https://media.springernature.com/lw703/springer-static/image/art%3A10.1038%2F528452a/MediaObjects/41586_2015_Article_BF528452a_Figg_HTML.jpg",
- myAccessRights: {
- read: true,
- write: false,
- delete: false,
- },
- accessRights: {
- 3: {
- read: true,
- write: false,
- delete: false,
- },
- 5: {
- read: true,
- write: true,
- delete: false,
- },
- 9: {
- read: true,
- write: true,
- delete: true,
- },
- },
- createdAt: "2024-04-24 12:03:05.15249",
- lastModified: "2024-06-21 13:00:40.33769",
- }],
+ createNewWorkspaceData: function(name, description = "", thumbnail = "") {
+ return {
+ name,
+ description,
+ thumbnail,
+ };
+ },
fetchWorkspaces: function() {
if (osparc.auth.Data.getInstance().isGuest()) {
@@ -125,40 +44,17 @@ qx.Class.define("osparc.store.Workspaces", {
});
}
- /*
- return osparc.data.Resources.getInstance().getAllPages("workspaces", params)
+ return osparc.data.Resources.getInstance().getAllPages("workspaces")
.then(workspacesData => {
- const workspaces = [];
workspacesData.forEach(workspaceData => {
const workspace = new osparc.data.model.Workspace(workspaceData);
this.__addToCache(workspace);
- workspaces.push(workspace);
});
- return workspaces;
+ return this.workspacesCached;
});
- */
-
- return new Promise(resolve => {
- if (this.workspacesCached.length === 0) {
- this.self().FAKE_WORKSPACES.forEach(workspaceData => {
- const workspace = new osparc.data.model.Workspace(workspaceData);
- this.__addToCache(workspace);
- });
- }
- resolve(this.workspacesCached);
- });
- },
-
- createNewWorkspaceData: function(name, description = "", thumbnail = "") {
- return {
- name,
- description,
- thumbnail,
- };
},
postWorkspace: function(newWorkspaceData) {
- /*
const params = {
data: newWorkspaceData
};
@@ -168,30 +64,10 @@ qx.Class.define("osparc.store.Workspaces", {
this.__addToCache(newWorkspace);
return newWorkspace;
});
- */
- const workspaceData = newWorkspaceData;
- workspaceData["workspaceId"] = Math.floor(Math.random() * 100) + 100;
- workspaceData["myAccessRights"] = osparc.share.CollaboratorsWorkspace.getOwnerAccessRight();
- const myGroupId = osparc.auth.Data.getInstance().getGroupId();
- workspaceData["accessRights"] = {};
- workspaceData["accessRights"][myGroupId] = osparc.share.CollaboratorsWorkspace.getOwnerAccessRight();
- workspaceData["createdAt"] = new Date().toISOString();
- workspaceData["lastModified"] = new Date().toISOString();
- return new Promise(resolve => {
- const workspace = new osparc.data.model.Workspace(workspaceData);
- this.__addToCache(workspace);
- resolve(workspace);
- });
},
deleteWorkspace: function(workspaceId) {
return new Promise((resolve, reject) => {
- if (this.__deleteFromCache(workspaceId)) {
- resolve();
- } else {
- reject();
- }
- /*
const params = {
"url": {
workspaceId
@@ -206,7 +82,6 @@ qx.Class.define("osparc.store.Workspaces", {
}
})
.catch(err => reject(err));
- */
});
},
@@ -228,66 +103,81 @@ qx.Class.define("osparc.store.Workspaces", {
workspace[setter](updateData[propKey]);
}
});
- workspace.setLastModified(new Date());
- this.__deleteFromCache(workspaceId);
- this.__addToCache(workspace);
- resolve();
+ workspace.set({
+ modifiedAt: new Date()
+ });
+ resolve(workspace);
})
.catch(err => reject(err));
});
},
addCollaborators: function(workspaceId, newCollaborators) {
- return new Promise((resolve, reject) => {
- const workspace = this.getWorkspace(workspaceId);
- if (workspace) {
- const accessRights = workspace.getAccessRights();
- const newAccessRights = Object.assign(accessRights, newCollaborators);
+ const promises = [];
+ Object.keys(newCollaborators).forEach(groupId => {
+ const params = {
+ url: {
+ workspaceId,
+ groupId,
+ },
+ data: newCollaborators[groupId]
+ };
+ promises.push(osparc.data.Resources.fetch("workspaces", "postAccessRights", params));
+ });
+ return Promise.all(promises)
+ .then(() => {
+ const workspace = this.getWorkspace(workspaceId);
+ const newAccessRights = workspace.getAccessRights();
+ Object.keys(newCollaborators).forEach(gid => {
+ newAccessRights[gid] = newCollaborators[gid];
+ });
workspace.set({
accessRights: newAccessRights,
- lastModified: new Date()
- })
- resolve();
- } else {
- reject();
- }
- });
+ modifiedAt: new Date()
+ });
+ })
+ .catch(console.error);
},
- removeCollaborator: function(workspaceId, gid) {
- return new Promise((resolve, reject) => {
- const workspace = this.getWorkspace(workspaceId);
- if (workspace) {
- const accessRights = workspace.getAccessRights();
- delete accessRights[gid];
- workspace.set({
- accessRights: accessRights,
- lastModified: new Date()
- })
- resolve();
- } else {
- reject();
+ removeCollaborator: function(workspaceId, groupId) {
+ const params = {
+ url: {
+ workspaceId,
+ groupId,
}
- });
+ };
+ return osparc.data.Resources.fetch("workspaces", "deleteAccessRights", params)
+ .then(() => {
+ const workspace = this.getWorkspace(workspaceId);
+ const newAccessRights = workspace.getAccessRights();
+ delete newAccessRights[groupId];
+ workspace.set({
+ accessRights: newAccessRights,
+ modifiedAt: new Date()
+ });
+ })
+ .catch(console.error);
},
- updateCollaborator: function(workspaceId, gid, newPermissions) {
- return new Promise((resolve, reject) => {
- const workspace = this.getWorkspace(workspaceId);
- if (workspace) {
- const accessRights = workspace.getAccessRights();
- if (gid in accessRights) {
- accessRights[gid] = newPermissions;
- workspace.set({
- accessRights: accessRights,
- lastModified: new Date()
- })
- resolve();
- return;
- }
- }
- reject();
- });
+ updateCollaborator: function(workspaceId, groupId, newPermissions) {
+ const params = {
+ url: {
+ workspaceId,
+ groupId,
+ },
+ data: newPermissions
+ };
+ return osparc.data.Resources.fetch("workspaces", "putAccessRights", params)
+ .then(() => {
+ const workspace = this.getWorkspace(workspaceId);
+ const newAccessRights = workspace.getAccessRights();
+ newAccessRights[groupId] = newPermissions;
+ workspace.set({
+ accessRights: workspace.newAccessRights,
+ modifiedAt: new Date()
+ });
+ })
+ .catch(console.error);
},
getWorkspaces: function(parentId = null) {
diff --git a/services/static-webserver/client/source/class/osparc/study/Utils.js b/services/static-webserver/client/source/class/osparc/study/Utils.js
index c41b7218813..b88ed539257 100644
--- a/services/static-webserver/client/source/class/osparc/study/Utils.js
+++ b/services/static-webserver/client/source/class/osparc/study/Utils.js
@@ -105,12 +105,13 @@ qx.Class.define("osparc.study.Utils", {
return isRetired;
},
- createStudyFromService: function(key, version, existingStudies, newStudyLabel) {
+ createStudyFromService: function(key, version, existingStudies, newStudyLabel, contextProps = {}) {
return new Promise((resolve, reject) => {
osparc.store.Services.getService(key, version)
.then(metadata => {
const newUuid = osparc.utils.Utils.uuidV4();
- const minStudyData = osparc.data.model.Study.createMyNewStudyObject();
+ // context props, otherwise Study will be created in the root folder of my personal workspace
+ const minStudyData = Object.assign(osparc.data.model.Study.createMinStudyObject(), contextProps);
if (newStudyLabel === undefined) {
newStudyLabel = metadata["name"];
}
@@ -181,7 +182,7 @@ qx.Class.define("osparc.study.Utils", {
});
},
- createStudyFromTemplate: function(templateData, loadingPage) {
+ createStudyFromTemplate: function(templateData, loadingPage, contextProps = {}) {
return new Promise((resolve, reject) => {
const inaccessibleServices = this.getInaccessibleServices(templateData["workbench"]);
if (inaccessibleServices.length) {
@@ -191,7 +192,8 @@ qx.Class.define("osparc.study.Utils", {
});
return;
}
- const minStudyData = osparc.data.model.Study.createMyNewStudyObject();
+ // context props, otherwise Study will be created in the root folder of my personal workspace
+ const minStudyData = Object.assign(osparc.data.model.Study.createMinStudyObject(), contextProps);
minStudyData["name"] = templateData["name"];
minStudyData["description"] = templateData["description"];
minStudyData["thumbnail"] = templateData["thumbnail"];