diff --git a/services/static-webserver/client/source/class/osparc/dashboard/ContainerHeader.js b/services/static-webserver/client/source/class/osparc/dashboard/ContainerHeader.js index a80f44e9e9e..6ae201b180f 100644 --- a/services/static-webserver/client/source/class/osparc/dashboard/ContainerHeader.js +++ b/services/static-webserver/client/source/class/osparc/dashboard/ContainerHeader.js @@ -106,7 +106,7 @@ qx.Class.define("osparc.dashboard.ContainerHeader", { if (workspaceId === -1) { rootButton = new qx.ui.form.Button(this.tr("Shared Workspaces"), osparc.store.Workspaces.iconPath()); } else { - const workspace = osparc.store.Workspaces.getWorkspace(workspaceId); + const workspace = osparc.store.Workspaces.getInstance().getWorkspace(workspaceId); rootButton = new qx.ui.form.Button(workspace.getName(), osparc.store.Workspaces.iconPath()); } } else { 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 0261f0195fe..2aae68b41a7 100644 --- a/services/static-webserver/client/source/class/osparc/dashboard/FolderButtonItem.js +++ b/services/static-webserver/client/source/class/osparc/dashboard/FolderButtonItem.js @@ -151,7 +151,7 @@ qx.Class.define("osparc.dashboard.FolderButtonItem", { }, __applyWorkspaceId: function(workspaceId) { - const workspace = osparc.store.Workspaces.getWorkspace(workspaceId); + const workspace = osparc.store.Workspaces.getInstance().getWorkspace(workspaceId); const accessRights = workspace ? workspace.getAccessRights() : {}; if (accessRights && Object.keys(accessRights).length) { const shareIcon = this.getChildControl("icon").getChildControl("shared-icon"); 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 0e20d800be6..64edfbc7dae 100644 --- a/services/static-webserver/client/source/class/osparc/dashboard/FoldersTree.js +++ b/services/static-webserver/client/source/class/osparc/dashboard/FoldersTree.js @@ -21,7 +21,7 @@ qx.Class.define("osparc.dashboard.FoldersTree", { construct: function(currentWorkspaceId) { this.__currentWorkspaceId = currentWorkspaceId; - const workspace = osparc.store.Workspaces.getWorkspace(this.__currentWorkspaceId); + const workspace = osparc.store.Workspaces.getInstance().getWorkspace(this.__currentWorkspaceId); const workspaceLabel = workspace ? workspace.getName() : "My Workspace"; const rootData = { label: workspaceLabel, diff --git a/services/static-webserver/client/source/class/osparc/dashboard/MoveResourceToWorkspace.js b/services/static-webserver/client/source/class/osparc/dashboard/MoveResourceToWorkspace.js index 1eae08216bb..942b21cc8ca 100644 --- a/services/static-webserver/client/source/class/osparc/dashboard/MoveResourceToWorkspace.js +++ b/services/static-webserver/client/source/class/osparc/dashboard/MoveResourceToWorkspace.js @@ -58,7 +58,7 @@ qx.Class.define("osparc.dashboard.MoveResourceToWorkspace", { let control; switch (id) { case "current-workspace": { - const workspace = osparc.store.Workspaces.getWorkspace(this.__currentWorkspaceId); + const workspace = osparc.store.Workspaces.getInstance().getWorkspace(this.__currentWorkspaceId); const currentWorkspaceName = workspace ? workspace.getName() : "My Workspace"; control = new qx.ui.basic.Label(this.tr("Current location: ") + currentWorkspaceName); this._add(control); 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 599329e615f..ba4b541ab8b 100644 --- a/services/static-webserver/client/source/class/osparc/dashboard/ResourceFilter.js +++ b/services/static-webserver/client/source/class/osparc/dashboard/ResourceFilter.js @@ -26,7 +26,6 @@ qx.Class.define("osparc.dashboard.ResourceFilter", { this.__resourceType = resourceType; this.__sharedWithButtons = []; - this.__workspaceButtons = []; this.__tagButtons = []; this.__serviceTypeButtons = []; @@ -42,11 +41,8 @@ qx.Class.define("osparc.dashboard.ResourceFilter", { members: { __resourceType: null, - __contextLayout: null, - __contextRadioGroup: null, __workspacesAndFoldersTree: null, __sharedWithButtons: null, - __workspaceButtons: null, __tagButtons: null, __serviceTypeButtons: null, @@ -88,10 +84,10 @@ qx.Class.define("osparc.dashboard.ResourceFilter", { /* SHARED WITH */ __createSharedWithFilterLayout: function() { - const layout = this.__contextLayout = new qx.ui.container.Composite(new qx.ui.layout.VBox(5)); + const sharedWithLayout = new qx.ui.container.Composite(new qx.ui.layout.VBox(5)); - const radioGroup = this.__contextRadioGroup = new qx.ui.form.RadioGroup(); - radioGroup.setAllowEmptySelection(false); + const sharedWithRadioGroup = new qx.ui.form.RadioGroup(); + sharedWithRadioGroup.setAllowEmptySelection(false); const options = osparc.dashboard.SearchBarFilter.getSharedWithOptions(this.__resourceType); options.forEach(option => { @@ -124,8 +120,8 @@ qx.Class.define("osparc.dashboard.ResourceFilter", { } button.id = option.id; - layout.add(button); - radioGroup.add(button); + sharedWithLayout.add(button); + sharedWithRadioGroup.add(button); button.addListener("execute", () => { this.fireDataEvent("changeSharedWith", { @@ -137,61 +133,13 @@ qx.Class.define("osparc.dashboard.ResourceFilter", { this.__sharedWithButtons.push(button); }); - return layout; + return sharedWithLayout; }, /* /SHARED WITH */ /* WORKSPACES */ - __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" - }); - 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 => { - const workspaceButton = new qx.ui.toolbar.RadioButton(null, osparc.store.Workspaces.iconPath(22)); - workspace.bind("name", workspaceButton, "label"); - workspaceButton.workspaceId = workspace.getWorkspaceId(); - this.__workspaceButtons.push(workspaceButton); - workspaceButton.set({ - appearance: "filter-toggle-button", - marginLeft: 15, - }); - this.__contextLayout.add(workspaceButton); - this.__contextRadioGroup.add(workspaceButton); - workspaceButton.addListener("execute", () => { - this.fireDataEvent("changeWorkspace", workspaceButton.workspaceId); - }, this); - }); - }) - .catch(console.error); - }, - workspaceSelected: function(workspaceId) { - const foundButton = this.__workspaceButtons.find(workspaceButton => workspaceButton.workspaceId === workspaceId); - if (foundButton) { - foundButton.execute(); - } + // OM: select folder }, /* /WORKSPACES */ 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 87d2279afa4..5fbc49b32f9 100644 --- a/services/static-webserver/client/source/class/osparc/dashboard/StudyBrowser.js +++ b/services/static-webserver/client/source/class/osparc/dashboard/StudyBrowser.js @@ -163,7 +163,7 @@ qx.Class.define("osparc.dashboard.StudyBrowser", { }, __reloadWorkspaces: function() { - osparc.store.Workspaces.fetchWorkspaces() + osparc.store.Workspaces.getInstance().fetchWorkspaces() .then(workspaces => { this.__workspacesList = workspaces; workspaces.forEach(workspace => workspace["resourceType"] = "workspace"); @@ -411,7 +411,6 @@ qx.Class.define("osparc.dashboard.StudyBrowser", { "updateWorkspace" ].forEach(e => { newWorkspaceCard.addListener(e, () => { - this._resourceFilter.reloadWorkspaceButtons(); this.__reloadWorkspaces(); }); }); @@ -420,6 +419,7 @@ qx.Class.define("osparc.dashboard.StudyBrowser", { _workspaceSelected: function(workspaceId) { this.setCurrentWorkspaceId(workspaceId); + this._changeContext(this.getCurrentWorkspaceId(), null); }, _workspaceUpdated: function() { @@ -427,9 +427,8 @@ qx.Class.define("osparc.dashboard.StudyBrowser", { }, _deleteWorkspaceRequested: function(workspaceId) { - osparc.store.Workspaces.deleteWorkspace(workspaceId) + osparc.store.Workspaces.getInstance().deleteWorkspace(workspaceId) .then(() => { - this._resourceFilter.reloadWorkspaceButtons(); this.__reloadWorkspaces(); }) .catch(err => console.error(err)); diff --git a/services/static-webserver/client/source/class/osparc/dashboard/WorkspaceHeader.js b/services/static-webserver/client/source/class/osparc/dashboard/WorkspaceHeader.js index 9fb3d526d13..7f89b8ae4b3 100644 --- a/services/static-webserver/client/source/class/osparc/dashboard/WorkspaceHeader.js +++ b/services/static-webserver/client/source/class/osparc/dashboard/WorkspaceHeader.js @@ -171,7 +171,7 @@ qx.Class.define("osparc.dashboard.WorkspaceHeader", { const title = this.getChildControl("title"); this.getChildControl("edit-button").exclude(); - const workspace = osparc.store.Workspaces.getWorkspace(workspaceId); + const workspace = osparc.store.Workspaces.getInstance().getWorkspace(workspaceId); if (workspaceId === -1) { this.__setIcon(osparc.store.Workspaces.iconPath(32)); title.setValue(this.tr("Shared Workspaces")); @@ -273,7 +273,7 @@ qx.Class.define("osparc.dashboard.WorkspaceHeader", { }, __editWorkspace: function() { - const workspace = osparc.store.Workspaces.getWorkspace(this.getCurrentWorkspaceId()); + const workspace = osparc.store.Workspaces.getInstance().getWorkspace(this.getCurrentWorkspaceId()); const permissionsView = new osparc.editor.WorkspaceEditor(workspace); const title = this.tr("Edit Workspace"); const win = osparc.ui.window.Window.popUpInWindow(permissionsView, title, 300, 200); @@ -284,7 +284,7 @@ qx.Class.define("osparc.dashboard.WorkspaceHeader", { }, __openShareWith: function() { - const workspace = osparc.store.Workspaces.getWorkspace(this.getCurrentWorkspaceId()); + const workspace = osparc.store.Workspaces.getInstance().getWorkspace(this.getCurrentWorkspaceId()); const permissionsView = new osparc.share.CollaboratorsWorkspace(workspace); const title = this.tr("Share Workspace"); const win = osparc.ui.window.Window.popUpInWindow(permissionsView, title, 500, 400); diff --git a/services/static-webserver/client/source/class/osparc/dashboard/WorkspacesAndFoldersTree.js b/services/static-webserver/client/source/class/osparc/dashboard/WorkspacesAndFoldersTree.js index 031e8356dc3..161471e3845 100644 --- a/services/static-webserver/client/source/class/osparc/dashboard/WorkspacesAndFoldersTree.js +++ b/services/static-webserver/client/source/class/osparc/dashboard/WorkspacesAndFoldersTree.js @@ -45,14 +45,33 @@ qx.Class.define("osparc.dashboard.WorkspacesAndFoldersTree", { this.__initTree(); osparc.store.Folders.getInstance().addListener("folderAdded", e => { - const folder = e.getData() + const folder = e.getData(); this.__folderAdded(folder); }, this); osparc.store.Folders.getInstance().addListener("folderRemoved", e => { - const folder = e.getData() + const folder = e.getData(); this.__folderRemoved(folder); }, this); + + osparc.store.Folders.getInstance().addListener("folderMoved", e => { + const { + folder, + oldParentFolderId, + } = e.getData(); + this.__folderRemoved(folder, oldParentFolderId); + this.__folderAdded(folder); + }, this); + + osparc.store.Workspaces.getInstance().addListener("workspaceAdded", e => { + const workspace = e.getData(); + this.__addWorkspace(workspace); + }, this); + + osparc.store.Workspaces.getInstance().addListener("workspaceRemoved", e => { + const workspace = e.getData(); + this.__removeWorkspace(workspace); + }, this); }, events: { @@ -159,16 +178,16 @@ qx.Class.define("osparc.dashboard.WorkspacesAndFoldersTree", { this.__models.push(sharedWorkspaceModel); rootModel.getChildren().append(sharedWorkspaceModel); - osparc.store.Workspaces.fetchWorkspaces() + osparc.store.Workspaces.getInstance().fetchWorkspaces() .then(workspaces => { workspaces.forEach(workspace => { - this.__addWorkspace(workspace, sharedWorkspaceModel); + this.__addWorkspace(workspace); }); }) .catch(console.error); }, - __addWorkspace: function(workspace, parentModel) { + __addWorkspace: function(workspace) { const workspaceData = { label: "", icon: "shared", @@ -182,7 +201,17 @@ qx.Class.define("osparc.dashboard.WorkspacesAndFoldersTree", { const workspaceModel = qx.data.marshal.Json.createModel(workspaceData, true); this.__models.push(workspaceModel); workspace.bind("name", workspaceModel, "label"); - parentModel.getChildren().append(workspaceModel); + + const sharedWorkspaceModel = this.__getModel(-1, null); + sharedWorkspaceModel.getChildren().append(workspaceModel); + }, + + __removeWorkspace: function(workspace) { + const sharedWorkspaceModel = this.__getModel(-1, null); + const idx = sharedWorkspaceModel.getChildren().toArray().findIndex(w => workspace.getWorkspaceId() === w.getWorkspaceId()); + if (idx > -1) { + sharedWorkspaceModel.getChildren().toArray().splice(idx, 1); + } }, __addFolder: function(folder, parentModel) { @@ -225,8 +254,9 @@ qx.Class.define("osparc.dashboard.WorkspacesAndFoldersTree", { } }, - __folderRemoved: function(folder) { - const parentModel = this.__getModel(folder.getWorkspaceId(), folder.getParentFolderId()); + __folderRemoved: function(folder, oldParentFolderId) { + // eslint-disable-next-line no-negated-condition + const parentModel = this.__getModel(folder.getWorkspaceId(), oldParentFolderId !== undefined ? oldParentFolderId : folder.getParentFolderId()); if (parentModel) { const idx = parentModel.getChildren().toArray().findIndex(c => folder.getWorkspaceId() === c.getWorkspaceId() && folder.getFolderId() === c.getFolderId()); if (idx > -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 index 5c853d273be..62bfa793320 100644 --- a/services/static-webserver/client/source/class/osparc/dashboard/WorkspacesTree.js +++ b/services/static-webserver/client/source/class/osparc/dashboard/WorkspacesTree.js @@ -95,7 +95,7 @@ qx.Class.define("osparc.dashboard.WorkspacesTree", { const myWorkspaceModel = qx.data.marshal.Json.createModel(myWorkspaceData, true); parent.getChildren().append(myWorkspaceModel); - osparc.store.Workspaces.fetchWorkspaces() + osparc.store.Workspaces.getInstance().fetchWorkspaces() .then(workspaces => { workspaces.forEach(workspace => { const workspaceData = { diff --git a/services/static-webserver/client/source/class/osparc/editor/WorkspaceEditor.js b/services/static-webserver/client/source/class/osparc/editor/WorkspaceEditor.js index 18ed3d79e10..367da6a4b77 100644 --- a/services/static-webserver/client/source/class/osparc/editor/WorkspaceEditor.js +++ b/services/static-webserver/client/source/class/osparc/editor/WorkspaceEditor.js @@ -176,7 +176,7 @@ qx.Class.define("osparc.editor.WorkspaceEditor", { description: this.getDescription(), thumbnail: this.getThumbnail(), }; - osparc.store.Workspaces.postWorkspace(newWorkspaceData) + osparc.store.Workspaces.getInstance().postWorkspace(newWorkspaceData) .then(newWorkspace => this.fireDataEvent("workspaceCreated", newWorkspace)) .catch(console.error) .finally(() => createButton.setFetching(false)); @@ -189,7 +189,7 @@ qx.Class.define("osparc.editor.WorkspaceEditor", { description: this.getDescription(), thumbnail: this.getThumbnail(), }; - osparc.store.Workspaces.putWorkspace(this.__workspaceId, updateData) + osparc.store.Workspaces.getInstance().putWorkspace(this.__workspaceId, updateData) .then(() => this.fireEvent("workspaceUpdated")) .catch(console.error) .finally(() => editButton.setFetching(false)); diff --git a/services/static-webserver/client/source/class/osparc/share/CollaboratorsWorkspace.js b/services/static-webserver/client/source/class/osparc/share/CollaboratorsWorkspace.js index 202d86b5e5d..63c2a33b9a9 100644 --- a/services/static-webserver/client/source/class/osparc/share/CollaboratorsWorkspace.js +++ b/services/static-webserver/client/source/class/osparc/share/CollaboratorsWorkspace.js @@ -70,7 +70,7 @@ qx.Class.define("osparc.share.CollaboratorsWorkspace", { const newCollaborators = {}; gids.forEach(gid => newCollaborators[gid] = this.self().getCollaboratorAccessRight()); - osparc.store.Workspaces.addCollaborators(this.__workspace.getWorkspaceId(), newCollaborators) + osparc.store.Workspaces.getInstance().addCollaborators(this.__workspace.getWorkspaceId(), newCollaborators) .then(() => { this.fireDataEvent("updateAccessRights", this.__workspace.serialize()); const text = this.tr("User(s) successfully added."); @@ -88,7 +88,7 @@ qx.Class.define("osparc.share.CollaboratorsWorkspace", { item.setEnabled(false); } - osparc.store.Workspaces.removeCollaborator(this.__workspace.getWorkspaceId(), collaborator["gid"]) + osparc.store.Workspaces.getInstance().removeCollaborator(this.__workspace.getWorkspaceId(), collaborator["gid"]) .then(() => { this.fireDataEvent("updateAccessRights", this.__workspace.serialize()); osparc.FlashMessenger.getInstance().logAs(this.tr("Member successfully removed")); @@ -108,7 +108,7 @@ qx.Class.define("osparc.share.CollaboratorsWorkspace", { __make: function(collaboratorGId, newAccessRights, successMsg, failureMsg, item) { item.setEnabled(false); - osparc.store.Workspaces.updateCollaborator(this.__workspace.getWorkspaceId(), collaboratorGId, newAccessRights) + osparc.store.Workspaces.getInstance().updateCollaborator(this.__workspace.getWorkspaceId(), collaboratorGId, newAccessRights) .then(() => { this.fireDataEvent("updateAccessRights", this.__workspace.serialize()); osparc.FlashMessenger.getInstance().logAs(successMsg); 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 969f7157002..087e0c75a2e 100644 --- a/services/static-webserver/client/source/class/osparc/store/Folders.js +++ b/services/static-webserver/client/source/class/osparc/store/Folders.js @@ -28,6 +28,7 @@ qx.Class.define("osparc.store.Folders", { events: { "folderAdded": "qx.event.type.Data", "folderRemoved": "qx.event.type.Data", + "folderMoved": "qx.event.type.Data", }, members: { @@ -92,20 +93,25 @@ qx.Class.define("osparc.store.Folders", { }, putFolder: function(folderId, updateData) { - return new Promise((resolve, reject) => { - const params = { - "url": { - folderId - }, - data: updateData - }; - osparc.data.Resources.getInstance().fetch("folders", "update", params) - .then(folderData => { - this.__addToCache(folderData); - resolve(); - }) - .catch(err => reject(err)); - }); + const folder = this.getFolder(folderId); + const oldParentFolderId = folder.getParentFolderId(); + const params = { + "url": { + folderId + }, + data: updateData + }; + return osparc.data.Resources.getInstance().fetch("folders", "update", params) + .then(folderData => { + this.__addToCache(folderData); + if (updateData.parentFolderId !== oldParentFolderId) { + this.fireDataEvent("folderMoved", { + folder, + oldParentFolderId, + }); + } + }) + .catch(console.error); }, getFolder: function(folderId = null) { 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 4d6e4e80de5..8d803de0af5 100644 --- a/services/static-webserver/client/source/class/osparc/store/Workspaces.js +++ b/services/static-webserver/client/source/class/osparc/store/Workspaces.js @@ -16,11 +16,21 @@ ************************************************************************ */ qx.Class.define("osparc.store.Workspaces", { - type: "static", + extend: qx.core.Object, + type: "singleton", - statics: { - workspacesCached: [], + construct: function() { + this.base(arguments); + + this.workspacesCached = []; + }, + + events: { + "workspaceAdded": "qx.event.type.Data", + "workspaceRemoved": "qx.event.type.Data", + }, + statics: { iconPath: function(iconsSize = 18) { const source = "@MaterialIcons/folder_shared/"; if (iconsSize === -1) { @@ -36,6 +46,10 @@ qx.Class.define("osparc.store.Workspaces", { thumbnail, }; }, + }, + + members: { + workspacesCached: null, fetchWorkspaces: function() { if (osparc.auth.Data.getInstance().isGuest()) { @@ -62,27 +76,26 @@ qx.Class.define("osparc.store.Workspaces", { .then(workspaceData => { const newWorkspace = new osparc.data.model.Workspace(workspaceData); this.__addToCache(newWorkspace); + this.fireDataEvent("workspaceAdded", newWorkspace); return newWorkspace; }); }, deleteWorkspace: function(workspaceId) { - return new Promise((resolve, reject) => { - const params = { - "url": { - workspaceId + const params = { + "url": { + workspaceId + } + }; + return osparc.data.Resources.getInstance().fetch("workspaces", "delete", params) + .then(() => { + const workspace = this.getWorkspace(workspaceId); + if (workspace) { + this.__deleteFromCache(workspaceId); + this.fireDataEvent("workspaceRemoved", workspace); } - }; - osparc.data.Resources.getInstance().fetch("workspaces", "delete", params) - .then(() => { - if (this.__deleteFromCache(workspaceId)) { - resolve(); - } else { - reject(); - } - }) - .catch(err => reject(err)); - }); + }) + .catch(console.error); }, putWorkspace: function(workspaceId, updateData) {