diff --git a/packages/models-library/src/models_library/api_schemas_dynamic_sidecar/ports.py b/packages/models-library/src/models_library/api_schemas_dynamic_sidecar/ports.py index 5863b53b2bc..01214a39537 100644 --- a/packages/models-library/src/models_library/api_schemas_dynamic_sidecar/ports.py +++ b/packages/models-library/src/models_library/api_schemas_dynamic_sidecar/ports.py @@ -11,14 +11,14 @@ class OutputStatus(StrAutoEnum): UPLOAD_STARTED = auto() UPLOAD_WAS_ABORTED = auto() UPLOAD_FINISHED_SUCCESSFULLY = auto() - UPLOAD_FINISHED_WITH_ERRROR = auto() + UPLOAD_FINISHED_WITH_ERROR = auto() class InputStatus(StrAutoEnum): DOWNLOAD_STARTED = auto() DOWNLOAD_WAS_ABORTED = auto() DOWNLOAD_FINISHED_SUCCESSFULLY = auto() - DOWNLOAD_FINISHED_WITH_ERRROR = auto() + DOWNLOAD_FINISHED_WITH_ERROR = auto() class _PortStatusCommon(BaseModel): diff --git a/services/dynamic-sidecar/src/simcore_service_dynamic_sidecar/modules/notifications/_notifications_ports.py b/services/dynamic-sidecar/src/simcore_service_dynamic_sidecar/modules/notifications/_notifications_ports.py index ae48f19a973..6a8c45e35da 100644 --- a/services/dynamic-sidecar/src/simcore_service_dynamic_sidecar/modules/notifications/_notifications_ports.py +++ b/services/dynamic-sidecar/src/simcore_service_dynamic_sidecar/modules/notifications/_notifications_ports.py @@ -52,7 +52,7 @@ async def send_output_port_upload_finished_with_error( self, port_key: ServicePortKey ) -> None: await self._send_output_port_status( - port_key, OutputStatus.UPLOAD_FINISHED_WITH_ERRROR + port_key, OutputStatus.UPLOAD_FINISHED_WITH_ERROR ) async def send_input_port_download_started(self, port_key: ServicePortKey) -> None: @@ -74,5 +74,5 @@ async def send_input_port_download_finished_with_error( self, port_key: ServicePortKey ) -> None: await self._send_input_port_status( - port_key, InputStatus.DOWNLOAD_FINISHED_WITH_ERRROR + port_key, InputStatus.DOWNLOAD_FINISHED_WITH_ERROR ) diff --git a/services/dynamic-sidecar/tests/unit/test_modules_notifier.py b/services/dynamic-sidecar/tests/unit/test_modules_notifier.py index 654d2bb1619..c7f7e770166 100644 --- a/services/dynamic-sidecar/tests/unit/test_modules_notifier.py +++ b/services/dynamic-sidecar/tests/unit/test_modules_notifier.py @@ -289,7 +289,7 @@ async def test_notifier_send_input_port_status( await port_notifier.send_input_port_download_finished_succesfully( port_key ) - case InputStatus.DOWNLOAD_FINISHED_WITH_ERRROR: + case InputStatus.DOWNLOAD_FINISHED_WITH_ERROR: await port_notifier.send_input_port_download_finished_with_error( port_key ) @@ -378,7 +378,7 @@ async def test_notifier_send_output_port_status( await port_notifier.send_output_port_upload_finished_successfully( port_key ) - case OutputStatus.UPLOAD_FINISHED_WITH_ERRROR: + case OutputStatus.UPLOAD_FINISHED_WITH_ERROR: await port_notifier.send_output_port_upload_finished_with_error( port_key ) diff --git a/services/static-webserver/client/compile.json b/services/static-webserver/client/compile.json index 780532e3cf0..7ede67de747 100644 --- a/services/static-webserver/client/compile.json +++ b/services/static-webserver/client/compile.json @@ -56,7 +56,7 @@ "class": "osparc.Application", "theme": "osparc.theme.products.s4l.ThemeDark", "name": "s4llite", - "title": "Sim4Life Lite", + "title": "Sim4Life.lite", "include": [ "iconfont.material.Load", "iconfont.fontawesome5.Load", diff --git a/services/static-webserver/client/source/class/osparc/dashboard/ContextBreadcrumbs.js b/services/static-webserver/client/source/class/osparc/dashboard/ContextBreadcrumbs.js index 49b1f812990..f31ad07941c 100644 --- a/services/static-webserver/client/source/class/osparc/dashboard/ContextBreadcrumbs.js +++ b/services/static-webserver/client/source/class/osparc/dashboard/ContextBreadcrumbs.js @@ -52,6 +52,10 @@ qx.Class.define("osparc.dashboard.ContextBreadcrumbs", { __rebuild: function() { this._removeAll(); + if (this.getCurrentWorkspaceId() === -2) { + return; + } + if (this.getCurrentFolderId()) { const currentFolder = osparc.store.Folders.getInstance().getFolder(this.getCurrentFolderId()); this.__createUpstreamButtons(currentFolder); diff --git a/services/static-webserver/client/source/class/osparc/dashboard/Dashboard.js b/services/static-webserver/client/source/class/osparc/dashboard/Dashboard.js index effe47c25c4..b26b4d52e17 100644 --- a/services/static-webserver/client/source/class/osparc/dashboard/Dashboard.js +++ b/services/static-webserver/client/source/class/osparc/dashboard/Dashboard.js @@ -138,7 +138,8 @@ qx.Class.define("osparc.dashboard.Dashboard", { }); const tabButton = tabPage.getChildControl("button"); tabButton.set({ - minWidth: 50 + minWidth: 50, + maxHeight: 36, }); tabButton.ttt = label; tabButton.getChildControl("label").set({ diff --git a/services/static-webserver/client/source/class/osparc/dashboard/FolderButtonBase.js b/services/static-webserver/client/source/class/osparc/dashboard/FolderButtonBase.js index 821c9d3455c..ff567a659cb 100644 --- a/services/static-webserver/client/source/class/osparc/dashboard/FolderButtonBase.js +++ b/services/static-webserver/client/source/class/osparc/dashboard/FolderButtonBase.js @@ -112,12 +112,10 @@ qx.Class.define("osparc.dashboard.FolderButtonBase", { }, _shouldApplyFilter: function(data) { - console.log("_shouldApplyFilter", data); return false; }, _shouldReactToFilter: function(data) { - console.log("_shouldReactToFilter", data); return false; } }, diff --git a/services/static-webserver/client/source/class/osparc/dashboard/GridButtonNew.js b/services/static-webserver/client/source/class/osparc/dashboard/GridButtonNew.js index 2ae24d22dd8..4a2a3577e31 100644 --- a/services/static-webserver/client/source/class/osparc/dashboard/GridButtonNew.js +++ b/services/static-webserver/client/source/class/osparc/dashboard/GridButtonNew.js @@ -37,6 +37,12 @@ qx.Class.define("osparc.dashboard.GridButtonNew", { }); if (title) { + title = osparc.utils.Utils.replaceTokens( + title, + "replace_me_product_name", + osparc.store.StaticInfo.getInstance().getDisplayName() + ); + const titleLabel = this.getChildControl("title"); titleLabel.set({ value: title, @@ -45,6 +51,12 @@ qx.Class.define("osparc.dashboard.GridButtonNew", { } if (description) { + description = osparc.utils.Utils.replaceTokens( + description, + "replace_me_product_name", + osparc.store.StaticInfo.getInstance().getDisplayName() + ); + const descLabel = this.getChildControl("subtitle-text"); descLabel.setValue(description.toString()); } diff --git a/services/static-webserver/client/source/class/osparc/dashboard/ListButtonNew.js b/services/static-webserver/client/source/class/osparc/dashboard/ListButtonNew.js index b979981a5a2..d9bb0679f46 100644 --- a/services/static-webserver/client/source/class/osparc/dashboard/ListButtonNew.js +++ b/services/static-webserver/client/source/class/osparc/dashboard/ListButtonNew.js @@ -34,6 +34,12 @@ qx.Class.define("osparc.dashboard.ListButtonNew", { }); if (title) { + title = osparc.utils.Utils.replaceTokens( + title, + "replace_me_product_name", + osparc.store.StaticInfo.getInstance().getDisplayName() + ); + const titleLabel = this.getChildControl("title"); titleLabel.set({ value: title, diff --git a/services/static-webserver/client/source/class/osparc/dashboard/NewStudies.js b/services/static-webserver/client/source/class/osparc/dashboard/NewStudies.js index a129fefe8db..7c01ff5c74d 100644 --- a/services/static-webserver/client/source/class/osparc/dashboard/NewStudies.js +++ b/services/static-webserver/client/source/class/osparc/dashboard/NewStudies.js @@ -167,14 +167,7 @@ qx.Class.define("osparc.dashboard.NewStudies", { const newStudyClicked = () => this.fireDataEvent("newStudyClicked", templateInfo); const title = templateInfo.title; - let desc = templateInfo.description; - if (desc) { - desc = osparc.utils.Utils.replaceTokens( - desc, - "replace_me_product_name", - osparc.store.StaticInfo.getInstance().getDisplayName() - ); - } + const desc = templateInfo.description; const newPlanButton = new osparc.dashboard.GridButtonNew(title, desc); newPlanButton.setCardKey(templateInfo.idToWidget); osparc.utils.Utils.setIdToWidget(newPlanButton, templateInfo.idToWidget); 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 4d1effc3e37..4982fcaefed 100644 --- a/services/static-webserver/client/source/class/osparc/dashboard/ResourceBrowserBase.js +++ b/services/static-webserver/client/source/class/osparc/dashboard/ResourceBrowserBase.js @@ -42,15 +42,15 @@ qx.Class.define("osparc.dashboard.ResourceBrowserBase", { const mainLayoutWithSideSpacers = new qx.ui.container.Composite(new qx.ui.layout.HBox(spacing)) this._addToMainLayout(mainLayoutWithSideSpacers); - this.__leftFilters = new qx.ui.container.Composite(new qx.ui.layout.VBox(10)).set({ + this.__leftFilters = new qx.ui.container.Composite(new qx.ui.layout.VBox(15)).set({ width: leftColumnWidth }); mainLayoutWithSideSpacers.add(this.__leftFilters); - this.__centerLayout = new qx.ui.container.Composite(new qx.ui.layout.VBox(10)); + this.__centerLayout = new qx.ui.container.Composite(new qx.ui.layout.VBox(15)); mainLayoutWithSideSpacers.add(this.__centerLayout); - const rightColum = new qx.ui.container.Composite(new qx.ui.layout.VBox(10)); + const rightColum = new qx.ui.container.Composite(new qx.ui.layout.VBox()); mainLayoutWithSideSpacers.add(rightColum, { flex: 1 }); @@ -236,6 +236,7 @@ qx.Class.define("osparc.dashboard.ResourceBrowserBase", { }); const textField = searchBarFilter.getChildControl("text-field"); osparc.utils.Utils.setIdToWidget(textField, "searchBarFilter-textField-"+this._resourceType); + this._addToLayout(searchBarFilter); }, @@ -356,6 +357,15 @@ qx.Class.define("osparc.dashboard.ResourceBrowserBase", { radioGroup.add(btn); }); + if (this._resourceType === "study") { + const viewMode = osparc.utils.Utils.localCache.getLocalStorageItem("studiesViewMode"); + if (viewMode) { + if (viewMode === "list") { + radioGroup.setSelection([listBtn]); + } + } + } + this._toolbar.add(viewModeLayout); }, 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 2a0abefe5df..f0d854b2222 100644 --- a/services/static-webserver/client/source/class/osparc/dashboard/ResourceContainerManager.js +++ b/services/static-webserver/client/source/class/osparc/dashboard/ResourceContainerManager.js @@ -32,10 +32,6 @@ qx.Class.define("osparc.dashboard.ResourceContainerManager", { this.__resourcesList = []; this.__groupedContainersList = []; - const containerHeader = this.__containerHeader = new osparc.dashboard.ContextBreadcrumbs(); - this._add(containerHeader); - containerHeader.setVisibility(osparc.utils.DisabledPlugins.isFoldersEnabled() ? "visible" : "excluded"); - const workspacesContainer = this.__workspacesContainer = new osparc.dashboard.ToggleButtonContainer(); workspacesContainer.setVisibility(osparc.utils.DisabledPlugins.isFoldersEnabled() ? "visible" : "excluded"); @@ -64,7 +60,7 @@ qx.Class.define("osparc.dashboard.ResourceContainerManager", { init: "grid", nullable: false, event: "changeMode", - apply: "reloadCards" + apply: "__reloadCards" }, groupBy: { @@ -117,8 +113,6 @@ qx.Class.define("osparc.dashboard.ResourceContainerManager", { __workspacesList: null, __resourcesList: null, __groupedContainersList: null, - __foldersLayout: null, - __containerHeader: null, __foldersContainer: null, __workspacesContainer: null, __nonGroupedContainer: null, @@ -163,10 +157,6 @@ qx.Class.define("osparc.dashboard.ResourceContainerManager", { } }, - getContainerHeader: function() { - return this.__containerHeader; - }, - getFlatList: function() { return this.__nonGroupedContainer; }, @@ -233,7 +223,10 @@ qx.Class.define("osparc.dashboard.ResourceContainerManager", { position: "bottom-right" }); card.setMenu(menu); - card.subscribeToFilterGroup("searchBarFilter"); + if (resourceData.type !== "study") { + // the backend will do the projects:search + card.subscribeToFilterGroup("searchBarFilter"); + } [ "updateStudy", @@ -284,6 +277,10 @@ qx.Class.define("osparc.dashboard.ResourceContainerManager", { this._removeAll(); }, + __reloadCards: function(mode) { + this.reloadCards(); + }, + __addFoldersContainer: function() { // add foldersContainer dynamically [ @@ -356,7 +353,6 @@ qx.Class.define("osparc.dashboard.ResourceContainerManager", { reloadWorkspaces: function() { this.__cleanAll(); - this._add(this.__containerHeader); this._add(this.__workspacesContainer); let workspacesCards = []; this.__workspacesList.forEach(workspaceData => workspacesCards.push(this.__workspaceToCard(workspaceData))); @@ -375,7 +371,6 @@ qx.Class.define("osparc.dashboard.ResourceContainerManager", { __createWorkspaceCard: function(workspace) { const card = new osparc.dashboard.WorkspaceButtonItem(workspace); - card.subscribeToFilterGroup("searchBarFilter"); [ "workspaceSelected", "workspaceUpdated", @@ -411,7 +406,6 @@ qx.Class.define("osparc.dashboard.ResourceContainerManager", { __createFolderCard: function(folder) { const card = new osparc.dashboard.FolderButtonItem(folder); - card.subscribeToFilterGroup("searchBarFilter"); [ "folderSelected", "folderUpdated", diff --git a/services/static-webserver/client/source/class/osparc/dashboard/ResourceDetails.js b/services/static-webserver/client/source/class/osparc/dashboard/ResourceDetails.js index 88675e85166..a1ae4d742fa 100644 --- a/services/static-webserver/client/source/class/osparc/dashboard/ResourceDetails.js +++ b/services/static-webserver/client/source/class/osparc/dashboard/ResourceDetails.js @@ -159,7 +159,11 @@ qx.Class.define("osparc.dashboard.ResourceDetails", { this.__openResource(); } }) - .catch(() => this.__openButton.setFetching(false)); + .catch(err => { + console.error(err); + osparc.FlashMessenger.logAs(err.message, "ERROR"); + this.__openButton.setFetching(false); + }); }, __confirmUpdate: function() { diff --git a/services/static-webserver/client/source/class/osparc/dashboard/SearchBarFilter.js b/services/static-webserver/client/source/class/osparc/dashboard/SearchBarFilter.js index 6f224e46d80..b836a93ef44 100644 --- a/services/static-webserver/client/source/class/osparc/dashboard/SearchBarFilter.js +++ b/services/static-webserver/client/source/class/osparc/dashboard/SearchBarFilter.js @@ -285,10 +285,6 @@ qx.Class.define("osparc.dashboard.SearchBarFilter", { }); }, - resetSharedWithActiveFilter: function() { - this.__removeChips("shared-with"); - this.__filter(); - }, setSharedWithActiveFilter: function(optionId, optionLabel) { this.__removeChips("shared-with"); @@ -353,9 +349,13 @@ qx.Class.define("osparc.dashboard.SearchBarFilter", { } }, - __resetFilters: function() { + resetFilters: function() { this.__removeChips(); this.getChildControl("text-field").resetValue(); + }, + + __resetFilters: function() { + this.resetFilters(); this.__filter(); }, 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 cab599b6bc9..ae1864c7514 100644 --- a/services/static-webserver/client/source/class/osparc/dashboard/StudyBrowser.js +++ b/services/static-webserver/client/source/class/osparc/dashboard/StudyBrowser.js @@ -125,7 +125,10 @@ qx.Class.define("osparc.dashboard.StudyBrowser", { // "Starting..." page this._hideLoadingPage(); }) - .catch(console.error); + .catch(err => { + console.error(err); + osparc.FlashMessenger.logAs(err.message, "ERROR"); + }); }, __getActiveStudy: function() { @@ -154,15 +157,6 @@ qx.Class.define("osparc.dashboard.StudyBrowser", { } }, - __reloadFoldersAndStudies: function() { - this.__reloadFolders(); - this.__reloadStudies(); - }, - - __reloadFilteredResources: function() { - this.__reloadFilteredStudies(); - }, - __reloadWorkspaces: function() { this.__setWorkspacesToList([]); osparc.store.Workspaces.getInstance().fetchWorkspaces() @@ -175,7 +169,7 @@ qx.Class.define("osparc.dashboard.StudyBrowser", { if (osparc.utils.DisabledPlugins.isFoldersEnabled()) { const folderId = this.getCurrentFolderId(); const workspaceId = this.getCurrentWorkspaceId(); - if (workspaceId === -1) { + if (workspaceId === -1 || workspaceId === -2) { return; } this.__setFoldersToList([]); @@ -192,7 +186,7 @@ qx.Class.define("osparc.dashboard.StudyBrowser", { return; } const workspaceId = this.getCurrentWorkspaceId(); - if (workspaceId === -1) { + if (workspaceId === -1) { // shared workspace listing return; } @@ -229,13 +223,21 @@ qx.Class.define("osparc.dashboard.StudyBrowser", { this._loadingResourcesBtn.setVisibility("visible"); this.__getNextStudiesRequest() .then(resp => { - if ( - resp["params"]["url"].workspaceId !== this.getCurrentWorkspaceId() || - resp["params"]["url"].folderId !== this.getCurrentFolderId() - ) { - // Context might have been changed while waiting for the response. - // The new call is on the ways and this can be ignored. - return; + const urlParams = resp["params"]["url"]; + // Context might have been changed while waiting for the response. + // The new call is on the way, therefore this response can be ignored. + if ("workspaceId" in urlParams) { + if ( + urlParams.workspaceId !== this.getCurrentWorkspaceId() || + urlParams.folderId !== this.getCurrentFolderId() + ) { + return; + } + } else if ("text" in urlParams) { + const currentFilterData = this._searchBarFilter.getFilterData(); + if (currentFilterData.text && urlParams.text !== encodeURIComponent(currentFilterData.text)) { + return; + } } const studies = resp["data"]; @@ -264,54 +266,19 @@ qx.Class.define("osparc.dashboard.StudyBrowser", { } } }) - .catch(err => console.error(err)) - .finally(() => { - this._loadingResourcesBtn.setFetching(false); - this._loadingResourcesBtn.setVisibility(this._resourcesContainer.getFlatList().nextRequest === null ? "excluded" : "visible"); - this._moreResourcesRequired(); - }); - }, - - __reloadFilteredStudies: function(text) { - if (this._loadingResourcesBtn.isFetching()) { - return; - } - this.__resetStudiesList(); - this._loadingResourcesBtn.setFetching(true); - this._loadingResourcesBtn.setVisibility("visible"); - const request = this.__getTextFilteredNextRequest(text); - request - .then(resp => { - const filteredStudies = resp["data"]; - this._resourcesContainer.getFlatList().nextRequest = resp["_links"]["next"]; - this.__addStudiesToList(filteredStudies); - }) - .catch(err => console.error(err)) - .finally(() => { - this._loadingResourcesBtn.setFetching(false); - this._loadingResourcesBtn.setVisibility(this._resourcesContainer.getFlatList().nextRequest === null ? "excluded" : "visible"); - this._moreResourcesRequired(); - }); - }, - - __reloadSortedByStudies: function() { - if (this._loadingResourcesBtn.isFetching()) { - return; - } - this.__resetStudiesList(); - this._loadingResourcesBtn.setFetching(true); - this._loadingResourcesBtn.setVisibility("visible"); - const request = this.__getSortedByNextRequest(); - request - .then(resp => { - const sortedStudies = resp["data"]; - this._resourcesContainer.getFlatList().nextRequest = resp["_links"]["next"]; - this.__addStudiesToList(sortedStudies); + .catch(err => { + console.error(err); + osparc.FlashMessenger.logAs(err.message, "ERROR"); + // stop fetching + if (this._resourcesContainer.getFlatList()) { + this._resourcesContainer.getFlatList().nextRequest = null; + } }) - .catch(err => console.error(err)) .finally(() => { this._loadingResourcesBtn.setFetching(false); - this._loadingResourcesBtn.setVisibility(this._resourcesContainer.getFlatList().nextRequest === null ? "excluded" : "visible"); + if (this._resourcesContainer.getFlatList()) { + this._loadingResourcesBtn.setVisibility(this._resourcesContainer.getFlatList().nextRequest === null ? "excluded" : "visible"); + } this._moreResourcesRequired(); }); }, @@ -460,7 +427,11 @@ qx.Class.define("osparc.dashboard.StudyBrowser", { }, __addNewFolderButton: function() { - if (this.getCurrentWorkspaceId()) { + const currentWorkspaceId = this.getCurrentWorkspaceId(); + if (currentWorkspaceId) { + if (currentWorkspaceId === -1 || currentWorkspaceId === -2) { + return; + } const currentWorkspace = osparc.store.Workspaces.getInstance().getWorkspace(this.getCurrentWorkspaceId()); if (currentWorkspace && !currentWorkspace.getMyAccessRights()["write"]) { // If user can't write in workspace, do not show plus button @@ -644,7 +615,7 @@ qx.Class.define("osparc.dashboard.StudyBrowser", { }, this); }, - __getNextRequestParams: function() { + __getNextPageParams: function() { if ("nextRequest" in this._resourcesContainer.getFlatList() && this._resourcesContainer.getFlatList().nextRequest !== null && osparc.utils.Utils.hasParamFromURL(this._resourcesContainer.getFlatList().nextRequest, "offset") && @@ -666,67 +637,25 @@ qx.Class.define("osparc.dashboard.StudyBrowser", { orderBy: JSON.stringify(this.getOrderBy()), } }; - const nextRequestParams = this.__getNextRequestParams(); - if (nextRequestParams) { - params.url.offset = nextRequestParams.offset; - params.url.limit = nextRequestParams.limit; - } - const options = { - resolveWResponse: true - }; - - params.url.workspaceId = this.getCurrentWorkspaceId(); - params.url.folderId = this.getCurrentFolderId(); - if (params.url.orderBy) { - return osparc.data.Resources.fetch("studies", "getPageSortBy", params, undefined, options); - } else if (params.url.search) { - return osparc.data.Resources.fetch("studies", "getPageSearch", params, undefined, options); - } - return osparc.data.Resources.fetch("studies", "getPage", params, undefined, options); - }, - __getTextFilteredNextRequest: function(text) { - const params = { - url: { - offset: 0, - limit: osparc.dashboard.ResourceBrowserBase.PAGINATED_STUDIES, - text - } - }; - const nextRequestParams = this.__getNextRequestParams(); - if (nextRequestParams) { - params.url.offset = nextRequestParams.offset; - params.url.limit = nextRequestParams.limit; + const nextPageParams = this.__getNextPageParams(); + if (nextPageParams) { + params.url.offset = nextPageParams.offset; + params.url.limit = nextPageParams.limit; } const options = { resolveWResponse: true }; - params.url.workspaceId = this.getCurrentWorkspaceId(); - params.url.folderId = this.getCurrentFolderId(); - return osparc.data.Resources.fetch("studies", "getPageSearch", params, undefined, options); - }, - - __getSortedByNextRequest: function() { - const params = { - url: { - offset: 0, - limit: osparc.dashboard.ResourceBrowserBase.PAGINATED_STUDIES, - orderBy: JSON.stringify(this.getOrderBy()) - } - }; - const nextRequestParams = this.__getNextRequestParams(); - if (nextRequestParams) { - params.url.offset = nextRequestParams.offset; - params.url.limit = nextRequestParams.limit; + const filterData = this._searchBarFilter.getFilterData(); + if (filterData.text) { + params.url.text = encodeURIComponent(filterData.text); // name, description and uuid + return osparc.data.Resources.fetch("studies", "getPageSearch", params, undefined, options); } - const options = { - resolveWResponse: true - }; params.url.workspaceId = this.getCurrentWorkspaceId(); params.url.folderId = this.getCurrentFolderId(); - return osparc.data.Resources.fetch("studies", "getPageSortBy", params, undefined, options); + return osparc.data.Resources.fetch("studies", "getPage", params, undefined, options); }, invalidateStudies: function() { @@ -736,8 +665,12 @@ qx.Class.define("osparc.dashboard.StudyBrowser", { }, __addNewStudyButtons: function() { - if (this.getCurrentWorkspaceId()) { - const currentWorkspace = osparc.store.Workspaces.getInstance().getWorkspace(this.getCurrentWorkspaceId()); + const currentWorkspaceId = this.getCurrentWorkspaceId(); + if (currentWorkspaceId) { + if (currentWorkspaceId === -2) { + return; + } + const currentWorkspace = osparc.store.Workspaces.getInstance().getWorkspace(currentWorkspaceId); if (currentWorkspace && !currentWorkspace.getMyAccessRights()["write"]) { // If user can't write in workspace, do not show plus buttons return; @@ -949,14 +882,25 @@ qx.Class.define("osparc.dashboard.StudyBrowser", { const folderId = context["folderId"]; this.__changeContext(workspaceId, folderId); }, this); + + this._searchBarFilter.addListener("filterChanged", e => { + const filterData = e.getData(); + if (filterData.text) { + this.__changeContext(-2, null); + } else { + // Back to My Workspace + this.__changeContext(null, null); + } + }); } }, __changeContext: function(workspaceId, folderId) { if (osparc.utils.DisabledPlugins.isFoldersEnabled()) { if ( - this.getCurrentWorkspaceId() === workspaceId && - this.getCurrentFolderId() === folderId + workspaceId !== -2 && // reload studies for a new search + workspaceId === this.getCurrentWorkspaceId() && + folderId === this.getCurrentFolderId() ) { // didn't really change return; @@ -971,10 +915,19 @@ qx.Class.define("osparc.dashboard.StudyBrowser", { this.invalidateStudies(); this._resourcesContainer.setResourcesToList([]); - if (workspaceId === -1) { + if (workspaceId === -2) { + // Search result: no folders, just studies + this.__setFoldersToList([]); + this.__reloadStudies(); + } else if (workspaceId === -1) { + // Workspaces + this._searchBarFilter.resetFilters(); this.__reloadWorkspaces(); } else { - this.__reloadFoldersAndStudies(); + // Actual workspace + this._searchBarFilter.resetFilters(); + this.__reloadFolders(); + this.__reloadStudies(); } // notify workspaceHeader @@ -1002,35 +955,12 @@ qx.Class.define("osparc.dashboard.StudyBrowser", { osparc.utils.Utils.setIdToWidget(sortByButton, "sortByButton"); sortByButton.addListener("sortByChanged", e => { this.setOrderBy(e.getData()) - this.__reloadSortedByStudies(); + this.__resetStudiesList(); + this.__reloadStudies(); }, this); this._toolbar.add(sortByButton); }, - __addShowSharedWithButton: function() { - const sharedWithButton = new osparc.dashboard.SharedWithMenuButton("study"); - sharedWithButton.set({ - appearance: "form-button-outlined" - }); - osparc.utils.Utils.setIdToWidget(sharedWithButton, "sharedWithButton"); - - sharedWithButton.addListener("sharedWith", e => { - const option = e.getData(); - this._searchBarFilter.setSharedWithActiveFilter(option.id, option.label); - }, this); - this._searchBarFilter.addListener("filterChanged", e => { - const filterData = e.getData(); - if (filterData.text) { - this.__reloadFilteredResources(filterData.text); - } else { - this.__reloadFoldersAndStudies(); - } - sharedWithButton.filterChanged(filterData); - }, this); - - this._toolbar.add(sharedWithButton); - }, - __createLoadMoreButton: function() { const mode = this._resourcesContainer.getMode(); const loadMoreBtn = this._loadingResourcesBtn = (mode === "grid") ? new osparc.dashboard.GridButtonLoadMore() : new osparc.dashboard.ListButtonLoadMore(); @@ -1097,7 +1027,10 @@ qx.Class.define("osparc.dashboard.StudyBrowser", { this.__moveStudyToFolder(studyData, destFolderId), ]) .then(() => this.__removeFromStudyList(studyData["uuid"])) - .catch(err => console.error(err)); + .catch(err => { + console.error(err); + osparc.FlashMessenger.logAs(err.message, "ERROR"); + }); }); this.resetSelection(); this.setMultiSelection(false); @@ -1156,6 +1089,9 @@ qx.Class.define("osparc.dashboard.StudyBrowser", { })) }); this.bind("multiSelection", selectButton, "value"); + this.bind("currentWorkspaceId", selectButton, "visibility", { + converter: currentWorkspaceId => [-2, -1].includes(currentWorkspaceId) ? "excluded" : "visible" + }); return selectButton; }, @@ -1393,7 +1329,7 @@ qx.Class.define("osparc.dashboard.StudyBrowser", { .then(() => this._updateStudyData(studyData)) .catch(err => { console.error(err); - const msg = this.tr("Something went wrong Renaming"); + const msg = err.message || this.tr("Something went wrong Renaming"); osparc.FlashMessenger.logAs(msg, "ERROR"); }); }, @@ -1403,7 +1339,7 @@ qx.Class.define("osparc.dashboard.StudyBrowser", { .then(() => this._updateStudyData(studyData)) .catch(err => { console.error(err); - const msg = this.tr("Something went wrong updating the Thumbnail"); + const msg = err.message || this.tr("Something went wrong updating the Thumbnail"); osparc.FlashMessenger.logAs(msg, "ERROR"); }); }, @@ -1444,7 +1380,10 @@ qx.Class.define("osparc.dashboard.StudyBrowser", { this.__moveStudyToFolder(studyData, destFolderId), ]) .then(() => this.__removeFromStudyList(studyData["uuid"])) - .catch(err => console.error(err)); + .catch(err => { + console.error(err); + osparc.FlashMessenger.logAs(err.message, "ERROR"); + }); }; if (destWorkspaceId === currentWorkspaceId) { moveStudy(); @@ -1577,8 +1516,9 @@ qx.Class.define("osparc.dashboard.StudyBrowser", { const pollTasks = osparc.data.PollTasks.getInstance(); pollTasks.createPollingTask(fetchPromise, interval) .then(task => this.__taskDuplicateReceived(task, studyData["name"])) - .catch(errMsg => { - const msg = this.tr("Something went wrong Duplicating the study
") + errMsg; + .catch(err => { + console.error(err); + const msg = err.message || this.tr("Something went wrong Duplicating"); osparc.FlashMessenger.logAs(msg, "ERROR"); }); }, @@ -1596,8 +1536,9 @@ qx.Class.define("osparc.dashboard.StudyBrowser", { exportTask.setSubtitle(textSuccess); }; osparc.utils.Utils.downloadLink(url, "POST", null, progressCB) - .catch(e => { - const msg = osparc.data.Resources.getErrorMsg(JSON.parse(e.response)) || this.tr("Something went wrong Exporting the study"); + .catch(err => { + console.error(err); + const msg = osparc.data.Resources.getErrorMsg(JSON.parse(err.response)) || this.tr("Something went wrong Exporting the study"); osparc.FlashMessenger.logAs(msg, "ERROR"); }) .finally(() => { 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 844004de698..22f238b0fd1 100644 --- a/services/static-webserver/client/source/class/osparc/dashboard/WorkspaceButtonBase.js +++ b/services/static-webserver/client/source/class/osparc/dashboard/WorkspaceButtonBase.js @@ -242,12 +242,10 @@ qx.Class.define("osparc.dashboard.WorkspaceButtonBase", { }, _shouldApplyFilter: function(data) { - console.log("_shouldApplyFilter", data); return false; }, _shouldReactToFilter: function(data) { - console.log("_shouldReactToFilter", data); return false; } }, 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 a8a96135663..819a8bf07bb 100644 --- a/services/static-webserver/client/source/class/osparc/dashboard/WorkspaceHeader.js +++ b/services/static-webserver/client/source/class/osparc/dashboard/WorkspaceHeader.js @@ -100,7 +100,7 @@ qx.Class.define("osparc.dashboard.WorkspaceHeader", { }); this._add(control); break; - case "title": + case "workspace-title": control = new qx.ui.basic.Label().set({ font: "text-16", alignY: "middle", @@ -178,37 +178,47 @@ qx.Class.define("osparc.dashboard.WorkspaceHeader", { __buildLayout: function(workspaceId) { this.getChildControl("icon"); - const title = this.getChildControl("title").set({ - cursor: "pointer" - }); - title.addListener("tap", () => { - const folderId = null; - this.setCurrentFolderId(folderId); - this.fireDataEvent("contextChanged", { - workspaceId, - folderId, - }); - }); - + const title = this.getChildControl("workspace-title"); this.getChildControl("breadcrumbs"); - this.getChildControl("edit-button").exclude(); this.resetAccessRights(); this.resetMyAccessRights(); - const workspace = osparc.store.Workspaces.getInstance().getWorkspace(workspaceId); - if (workspaceId === -1) { + if (workspaceId === -2) { + this.__setIcon("@FontAwesome5Solid/search/24"); + title.set({ + value: this.tr("Search results"), + cursor: "auto", + }); + } else if (workspaceId === -1) { this.__setIcon(osparc.store.Workspaces.iconPath(32)); - title.setValue(this.tr("Shared Workspaces")); - } else if (workspace) { - const thumbnail = workspace.getThumbnail(); - this.__setIcon(thumbnail ? thumbnail : osparc.store.Workspaces.iconPath(32)); - workspace.bind("name", title, "value"); - workspace.bind("accessRights", this, "accessRights"); - workspace.bind("myAccessRights", this, "myAccessRights"); + title.set({ + value: this.tr("Shared Workspaces"), + cursor: "auto", + }) } else { - this.__setIcon("@FontAwesome5Solid/home/30"); - title.setValue(this.tr("My Workspace")); + title.set({ + cursor: "pointer" + }); + title.addListener("tap", () => { + const folderId = null; + this.setCurrentFolderId(folderId); + this.fireDataEvent("contextChanged", { + workspaceId, + folderId, + }); + }); + const workspace = osparc.store.Workspaces.getInstance().getWorkspace(workspaceId); + if (workspace) { + const thumbnail = workspace.getThumbnail(); + this.__setIcon(thumbnail ? thumbnail : osparc.store.Workspaces.iconPath(32)); + workspace.bind("name", title, "value"); + workspace.bind("accessRights", this, "accessRights"); + workspace.bind("myAccessRights", this, "myAccessRights"); + } else { + this.__setIcon("@FontAwesome5Solid/home/30"); + title.setValue(this.tr("My Workspace")); + } } }, @@ -221,15 +231,21 @@ qx.Class.define("osparc.dashboard.WorkspaceHeader", { this._add(spacer); }, - __setIcon: function(source) { + __resetIcon: function() { const icon = this.getChildControl("icon"); const image = icon.getChildControl("image"); image.resetSource(); icon.getContentElement().setStyles({ "background-image": "none" }); + }, + __setIcon: function(source) { + this.__resetIcon(); + + const icon = this.getChildControl("icon"); if (source.includes("@")) { + const image = icon.getChildControl("image"); image.set({ source }); 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 010deb4445b..46382726935 100644 --- a/services/static-webserver/client/source/class/osparc/dashboard/WorkspacesAndFoldersTree.js +++ b/services/static-webserver/client/source/class/osparc/dashboard/WorkspacesAndFoldersTree.js @@ -292,10 +292,12 @@ qx.Class.define("osparc.dashboard.WorkspacesAndFoldersTree", { const workspaceId = this.getCurrentWorkspaceId(); const folderId = this.getCurrentFolderId(); + const selection = this.getSelection(); + if (selection) { + selection.removeAll(); + } const contextModel = this.__getModel(workspaceId, folderId); if (contextModel) { - const selection = this.getSelection(); - selection.removeAll(); selection.push(contextModel); } }, diff --git a/services/static-webserver/client/source/class/osparc/dashboard/WorkspacesAndFoldersTreeItem.js b/services/static-webserver/client/source/class/osparc/dashboard/WorkspacesAndFoldersTreeItem.js index 5039a743a07..f643218243b 100644 --- a/services/static-webserver/client/source/class/osparc/dashboard/WorkspacesAndFoldersTreeItem.js +++ b/services/static-webserver/client/source/class/osparc/dashboard/WorkspacesAndFoldersTreeItem.js @@ -27,7 +27,7 @@ qx.Class.define("osparc.dashboard.WorkspacesAndFoldersTreeItem", { }); this.set({ - maxWidth: 200 - 10 + maxWidth: osparc.dashboard.ResourceBrowserBase.SIDE_SPACER_WIDTH - 12 }); this.setNotHoveredStyle(); 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 d4b5c86e6ac..ac1cddbdda5 100644 --- a/services/static-webserver/client/source/class/osparc/data/Resources.js +++ b/services/static-webserver/client/source/class/osparc/data/Resources.js @@ -119,18 +119,15 @@ qx.Class.define("osparc.data.Resources", { url: statics.API + "/projects?type=user" }, getPage: { - method: "GET", - url: statics.API + "/projects?type=user&offset={offset}&limit={limit}&workspace_id={workspaceId}&folder_id={folderId}" - }, - getPageSearch: { useCache: false, method: "GET", - url: statics.API + "/projects?type=user&offset={offset}&limit={limit}&workspace_id={workspaceId}&folder_id={folderId}&search={text}" + url: statics.API + "/projects?type=user&offset={offset}&limit={limit}&workspace_id={workspaceId}&folder_id={folderId}&order_by={orderBy}" }, - getPageSortBy: { + getPageSearch: { useCache: false, method: "GET", - url: statics.API + "/projects?type=user&offset={offset}&limit={limit}&workspace_id={workspaceId}&folder_id={folderId}&order_by={orderBy}" + url: statics.API + "/projects:search?offset={offset}&limit={limit}&text={text}&order_by={orderBy}" + // url: statics.API + "/projects:search?offset={offset}&limit={limit}&text={text}&tags={tags}&order_by={orderBy}" }, getOne: { useCache: false, @@ -1305,8 +1302,11 @@ qx.Class.define("osparc.data.Resources", { let status = null; if (e.getData().error) { const errorData = e.getData().error; + if (errorData.message) { + message = errorData.message; + } const logs = errorData.logs || null; - if (logs && logs.length) { + if (message === null && logs && logs.length) { message = logs[0].message; } const errors = errorData.errors || []; diff --git a/services/static-webserver/client/source/class/osparc/data/model/IframeHandler.js b/services/static-webserver/client/source/class/osparc/data/model/IframeHandler.js index 39dbde53c8f..1dd46c13b13 100644 --- a/services/static-webserver/client/source/class/osparc/data/model/IframeHandler.js +++ b/services/static-webserver/client/source/class/osparc/data/model/IframeHandler.js @@ -23,6 +23,12 @@ qx.Class.define("osparc.data.model.IframeHandler", { this.setStudy(study); this.setNode(node); + node.getStatus().addListener("changeInteractive", e => { + const newStatus = e.getData(); + const oldStatus = e.getOldData(); + this.__statusInteractiveChanged(newStatus, oldStatus); + }); + this.__initLoadingPage(); this.__initIFrame(); }, @@ -51,12 +57,6 @@ qx.Class.define("osparc.data.model.IframeHandler", { check: "osparc.widget.PersistentIframe", init: null, nullable: true - }, - - polling: { - check: "Boolean", - init: null, - nullable: true } }, @@ -69,12 +69,7 @@ qx.Class.define("osparc.data.model.IframeHandler", { __stopRequestingStatus: null, __retriesLeft: null, - startPolling: function() { - if (this.isPolling()) { - return; - } - this.setPolling(true); - + checkState: function() { this.getNode().getStatus().getProgressSequence() .resetSequence(); @@ -87,7 +82,7 @@ qx.Class.define("osparc.data.model.IframeHandler", { .resetSequence(); this.__unresponsiveRetries = 5; - this.__nodeState(false); + this.__nodeState(); this.getIFrame().resetSource(); }, @@ -124,47 +119,27 @@ qx.Class.define("osparc.data.model.IframeHandler", { }); loadingPage.addExtraWidget(sequenceWidget); - nodeStatus.addListener("changeInteractive", () => { - loadingPage.setHeader(this.__getLoadingPageHeader()); - const status = nodeStatus.getInteractive(); - if (["idle", "failed"].includes(status)) { - const startButton = new qx.ui.form.Button().set({ - label: this.tr("Start"), - icon: "@FontAwesome5Solid/play/18", - font: "text-18", - allowGrowX: false, - height: 32 - }); - startButton.addListener("execute", () => node.requestStartNode()); - loadingPage.addWidgetToMessages(startButton); - } else { - loadingPage.setMessages([]); - } - }, this); this.setLoadingPage(loadingPage); }, - __getLoadingPageHeader: function() { + __getLoadingPageHeader: function(status) { const node = this.getNode(); - let statusText = this.tr("Starting"); - const status = node.getStatus().getInteractive(); - if (status) { - statusText = status.charAt(0).toUpperCase() + status.slice(1); + if (status === undefined) { + status = node.getStatus().getInteractive(); } + const statusText = status ? (status.charAt(0).toUpperCase() + status.slice(1)) : this.tr("Starting"); const metadata = node.getMetaData(); const versionDisplay = osparc.service.Utils.extractVersionDisplay(metadata); return statusText + " " + node.getLabel() + " v" + versionDisplay + ""; }, - __nodeState: function(starting=true) { + __nodeState: function() { // Check if study is still there if (this.getStudy() === null || this.__stopRequestingStatus === true) { - this.setPolling(false); return; } // Check if node is still there if (this.getStudy().getWorkbench().getNode(this.getNode().getNodeId()) === null) { - this.setPolling(false); return; } @@ -176,7 +151,7 @@ qx.Class.define("osparc.data.model.IframeHandler", { } }; osparc.data.Resources.fetch("studies", "getNode", params) - .then(data => this.__onNodeState(data, starting)) + .then(data => this.onNodeState(data)) .catch(err => { let errorMsg = `Error retrieving ${node.getLabel()} status: ${err}`; if ("status" in err && err.status === 406) { @@ -191,7 +166,6 @@ qx.Class.define("osparc.data.model.IframeHandler", { }; node.fireDataEvent("showInLogger", errorMsgData); if ("status" in err && err.status === 406) { - this.setPolling(false); return; } if (this.__unresponsiveRetries > 0) { @@ -203,32 +177,24 @@ qx.Class.define("osparc.data.model.IframeHandler", { }; node.fireDataEvent("showInLogger", retryMsgData); this.__unresponsiveRetries--; - const interval = Math.floor(Math.random() * 5000) + 3000; - setTimeout(() => this.__nodeState(), interval); } else { - this.setPolling(false); node.getStatus().setInteractive("failed"); osparc.FlashMessenger.getInstance().logAs(this.tr("There was an error starting") + " " + node.getLabel(), "ERROR"); } }); }, - __onNodeState: function(data, starting=true) { + onNodeState: function(data) { const serviceState = data["service_state"]; const nodeId = data["service_uuid"]; const node = this.getNode(); const status = node.getStatus(); - let nextPollIn = null; - let pollingInNextStage = null; switch (serviceState) { case "idle": { status.setInteractive(serviceState); - if (starting && this.__unresponsiveRetries>0) { + if (this.__unresponsiveRetries>0) { // a bit of a hack. We will get rid of it when the backend pushes the states this.__unresponsiveRetries--; - nextPollIn = 2000; - } else { - this.setPolling(false); } break; } @@ -248,7 +214,6 @@ qx.Class.define("osparc.data.model.IframeHandler", { node.fireDataEvent("showInLogger", msgData); } status.setInteractive(serviceState); - nextPollIn = 10000; break; } case "stopping": @@ -256,28 +221,25 @@ qx.Class.define("osparc.data.model.IframeHandler", { case "starting": case "pulling": { status.setInteractive(serviceState); - nextPollIn = 5000; break; } case "running": { if (nodeId !== node.getNodeId()) { break; } - if (!starting) { - status.setInteractive("stopping"); - nextPollIn = 5000; - break; - } const { srvUrl, isDynamicV2 } = osparc.utils.Utils.computeServiceUrl(data); node.setDynamicV2(isDynamicV2); - if (srvUrl) { + if ( + srvUrl && + srvUrl !== node.getServiceUrl() // if it's already connected, do not restart the connection process + ) { + this.__statusInteractiveChanged("connecting", node.getStatus().getInteractive()); this.__retriesLeft = 40; this.__waitForServiceReady(srvUrl); } - pollingInNextStage = true; break; } case "complete": @@ -297,18 +259,10 @@ qx.Class.define("osparc.data.model.IframeHandler", { console.error(serviceState, "service state not supported"); break; } - if (nextPollIn) { - qx.event.Timer.once(() => this.__nodeState(starting), this, nextPollIn); - } else if (pollingInNextStage !== true) { - this.setPolling(false); - } }, __waitForServiceReady: function(srvUrl) { - this.getNode().getStatus().setInteractive("connecting"); - if (this.__retriesLeft === 0) { - this.setPolling(false); return; } @@ -317,7 +271,6 @@ qx.Class.define("osparc.data.model.IframeHandler", { // Check if node is still there if (this.getStudy().getWorkbench().getNode(this.getNode().getNodeId()) === null) { - this.setPolling(false); return; } const interval = 5000; @@ -335,7 +288,6 @@ qx.Class.define("osparc.data.model.IframeHandler", { console.log("Connecting: fetch's response status", response.status); } if (response.status < 400) { - this.setPolling(false); this.__serviceReadyIn(srvUrl); } else { console.log(`Connecting: ${srvUrl} is not reachable. Status: ${response.status}`); @@ -356,16 +308,57 @@ qx.Class.define("osparc.data.model.IframeHandler", { const node = this.getNode(); node.setServiceUrl(srvUrl); node.getStatus().setInteractive("ready"); - const msg = "Service ready on " + srvUrl; - const msgData = { - nodeId: node.getNodeId(), - msg, - level: "INFO" - }; - node.fireDataEvent("showInLogger", msgData); - this.__restartIFrame(); - if (!node.isDynamicV2()) { - node.callRetrieveInputs(); + }, + + __statusInteractiveChanged: function(status, oldStatus) { + if (status === oldStatus) { + return; + } + + const node = this.getNode(); + + const loadingPage = node.getLoadingPage(); + loadingPage.setHeader(this.__getLoadingPageHeader(status)); + loadingPage.clearMessages(); + if (["idle", "failed"].includes(status)) { + const startButton = new qx.ui.form.Button().set({ + label: this.tr("Start"), + icon: "@FontAwesome5Solid/play/18", + font: "text-18", + allowGrowX: false, + height: 32 + }); + startButton.addListener("execute", () => node.requestStartNode()); + loadingPage.addWidgetToMessages(startButton); + } + + if (status === "ready") { + const msg = `Service ${node.getLabel()} ${status}`; + const msgData = { + nodeId: node.getNodeId(), + msg, + level: "INFO" + }; + node.fireDataEvent("showInLogger", msgData); + + // will switch to iframe's content + this.__restartIFrame(); + if (!node.isDynamicV2()) { + node.callRetrieveInputs(); + } + } else if (["idle", "failed", "stopping"].includes(status) && oldStatus) { + const msg = `Service ${node.getLabel()} ${status}`; + const msgData = { + nodeId: node.getNodeId(), + msg, + level: "INFO" + }; + node.fireDataEvent("showInLogger", msgData); + + // will switch to the loading page + node.resetServiceUrl(); + this.getIFrame().resetSource(); + this.fireEvent("iframeChanged"); } }, @@ -394,7 +387,7 @@ qx.Class.define("osparc.data.model.IframeHandler", { const node = this.getNode(); const status = node.getStatus().getInteractive(); // it might have been stopped - if (status === "ready") { + if (["running", "ready"].includes(status)) { this.getIFrame().resetSource(); this.getIFrame().setSource(node.getServiceUrl()); diff --git a/services/static-webserver/client/source/class/osparc/data/model/Node.js b/services/static-webserver/client/source/class/osparc/data/model/Node.js index 6373d8835ca..c54e7e1cf0e 100644 --- a/services/static-webserver/client/source/class/osparc/data/model/Node.js +++ b/services/static-webserver/client/source/class/osparc/data/model/Node.js @@ -905,7 +905,7 @@ qx.Class.define("osparc.data.model.Node", { } }; osparc.data.Resources.fetch("studies", "startNode", params) - .then(() => this.startPollingState()) + .then(() => this.checkState()) .catch(err => { if ("status" in err && (err.status === 409 || err.status === 402)) { osparc.FlashMessenger.getInstance().logAs(err.message, "WARNING"); @@ -1055,7 +1055,7 @@ qx.Class.define("osparc.data.model.Node", { } }, - startPollingState: function() { + checkState: function() { if (this.isDynamic()) { const metadata = this.getMetaData(); const msg = "Starting " + metadata.key + ":" + metadata.version + "..."; @@ -1067,7 +1067,7 @@ qx.Class.define("osparc.data.model.Node", { this.fireDataEvent("showInLogger", msgData); if (this.getIframeHandler()) { - this.getIframeHandler().startPolling(); + this.getIframeHandler().checkState(); } else { console.error(this.getLabel() + " iframe handler not ready"); } 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 c62549bcc63..2d4633dd584 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 @@ -45,6 +45,7 @@ qx.Class.define("osparc.data.model.Study", { this.set({ uuid: studyData.uuid || this.getUuid(), workspaceId: studyData.workspaceId || null, + folderId: studyData.folderId || null, name: studyData.name || this.getName(), description: studyData.description || this.getDescription(), thumbnail: studyData.thumbnail || this.getThumbnail(), @@ -86,6 +87,13 @@ qx.Class.define("osparc.data.model.Study", { event: "changeWorkspaceId" }, + folderId: { + check: "Number", + init: true, + nullable: true, + event: "changeFolderId" + }, + name: { check: "String", nullable: false, diff --git a/services/static-webserver/client/source/class/osparc/data/model/Workbench.js b/services/static-webserver/client/source/class/osparc/data/model/Workbench.js index 3120a22f7f1..63cd8212fe2 100644 --- a/services/static-webserver/client/source/class/osparc/data/model/Workbench.js +++ b/services/static-webserver/client/source/class/osparc/data/model/Workbench.js @@ -104,7 +104,7 @@ qx.Class.define("osparc.data.model.Workbench", { initWorkbench: function() { const allModels = this.getNodes(); const nodes = Object.values(allModels); - nodes.forEach(node => node.startPollingState()); + nodes.forEach(node => node.checkState()); }, getUpstreamCompNodes: function(node, recursive = true, upstreamNodes = new Set()) { @@ -306,7 +306,7 @@ qx.Class.define("osparc.data.model.Workbench", { node.populateNodeData(); this.giveUniqueNameToNode(node, node.getLabel()); - node.startPollingState(); + node.checkState(); return node; } catch (err) { diff --git a/services/static-webserver/client/source/class/osparc/desktop/StudyEditor.js b/services/static-webserver/client/source/class/osparc/desktop/StudyEditor.js index 1218c22fc55..5b1e0764b18 100644 --- a/services/static-webserver/client/source/class/osparc/desktop/StudyEditor.js +++ b/services/static-webserver/client/source/class/osparc/desktop/StudyEditor.js @@ -287,6 +287,7 @@ qx.Class.define("osparc.desktop.StudyEditor", { this.__listenToNodeProgress(); this.__listenToNoMoreCreditsEvents(); this.__listenToEvent(); + this.__listenToServiceStatus(); }, __listenToLogger: function() { @@ -414,6 +415,26 @@ qx.Class.define("osparc.desktop.StudyEditor", { } }, + __listenToServiceStatus: function() { + const socket = osparc.wrapper.WebSocket.getInstance(); + + // callback for events + if (!socket.slotExists("serviceStatus")) { + socket.on("serviceStatus", data => { + const nodeId = data["service_uuid"]; + const workbench = this.getStudy().getWorkbench(); + const node = workbench.getNode(nodeId); + if (node) { + if (node.getIframeHandler()) { + node.getIframeHandler().onNodeState(data); + } + } else if (osparc.data.Permissions.getInstance().isTester()) { + console.log("Ignored ws 'progress' msg", data); + } + }, this); + } + }, + __reloadSnapshotsAndIterations: function() { const isVCDisabled = osparc.utils.DisabledPlugins.isVersionControlDisabled(); if (!isVCDisabled) { diff --git a/services/static-webserver/client/source/class/osparc/desktop/organizations/ServicesList.js b/services/static-webserver/client/source/class/osparc/desktop/organizations/ServicesList.js index 6a212375312..9d2d7a6fa1e 100644 --- a/services/static-webserver/client/source/class/osparc/desktop/organizations/ServicesList.js +++ b/services/static-webserver/client/source/class/osparc/desktop/organizations/ServicesList.js @@ -88,7 +88,7 @@ qx.Class.define("osparc.desktop.organizations.ServicesList", { item.addListener("openMoreInfo", e => { const serviceKey = e.getData()["key"]; const serviceVersion = e.getData()["version"]; - osparc.store.Store.getService(serviceKey, serviceVersion) + osparc.store.Services.getService(serviceKey, serviceVersion) .then(serviceData => { if (serviceData) { serviceData["resourceType"] = "service"; diff --git a/services/static-webserver/client/source/class/osparc/navigation/NavigationBar.js b/services/static-webserver/client/source/class/osparc/navigation/NavigationBar.js index f926f95b6e0..d3b00b12978 100644 --- a/services/static-webserver/client/source/class/osparc/navigation/NavigationBar.js +++ b/services/static-webserver/client/source/class/osparc/navigation/NavigationBar.js @@ -50,7 +50,6 @@ qx.Class.define("osparc.navigation.NavigationBar", { paddingLeft: 10, paddingRight: 10, height: this.self().HEIGHT, - backgroundColor: "navigation_bar_background_color" }); osparc.utils.Utils.setIdToWidget(this, "navigationBar"); diff --git a/services/static-webserver/client/source/class/osparc/product/AboutProduct.js b/services/static-webserver/client/source/class/osparc/product/AboutProduct.js index a7300e09031..97e18eeadfd 100644 --- a/services/static-webserver/client/source/class/osparc/product/AboutProduct.js +++ b/services/static-webserver/client/source/class/osparc/product/AboutProduct.js @@ -108,14 +108,14 @@ qx.Class.define("osparc.product.AboutProduct", { __buildS4LLiteLayout: function() { // https://zurichmedtech.github.io/s4l-lite-manual/#/docs/what_is_s4l_lite - const introText = "S4Llite is a powerful web-based simulation platform that allows you to model and analyze real-world phenomena and to design complex technical devices in a validated environment. With its intuitive interface and advanced tools, S4Llite makes it easy to develop your simulation project, wherever you are."; + const introText = "Sim4Life.lite is a powerful web-based simulation platform that allows you to model and analyze real-world phenomena and to design complex technical devices in a validated environment. With its intuitive interface and advanced tools, Sim4Life.lite makes it easy to develop your simulation project, wherever you are."; const licenseUrl = "https://zurichmedtech.github.io/s4l-lite-manual/#/docs/licensing/copyright_Sim4Life"; const licenseText = `Click ${osparc.utils.Utils.createHTMLLink("here", licenseUrl)} to read the license agreements.`; // more info ZMT website const moreInfoUrl = "https://zmt.swiss/"; - const moreInfoText = `For more information about S4Llite, visit ${osparc.utils.Utils.createHTMLLink("our website", moreInfoUrl)}.`; + const moreInfoText = `For more information about Sim4Life.lite, visit ${osparc.utils.Utils.createHTMLLink("our website", moreInfoUrl)}.`; [ introText, diff --git a/services/static-webserver/client/source/class/osparc/product/quickStart/s4llite/Dashboard.js b/services/static-webserver/client/source/class/osparc/product/quickStart/s4llite/Dashboard.js index 6075367284e..8b6e54d7bb2 100644 --- a/services/static-webserver/client/source/class/osparc/product/quickStart/s4llite/Dashboard.js +++ b/services/static-webserver/client/source/class/osparc/product/quickStart/s4llite/Dashboard.js @@ -40,7 +40,7 @@ qx.Class.define("osparc.product.quickStart.s4llite.Dashboard", { this._add(dashboardProjects); const newProjectText = this.tr("\ - 1) Start S4Llite: Click the + Start S4Llite button to create a new project. This will start the user interface of S4Llite.\ + 1) Start Sim4Life.lite: Click the + Start Sim4Life.lite button to create a new project. This will start the user interface of Sim4Life.lite.\ "); const newProject = osparc.product.quickStart.Utils.createLabel(newProjectText); this._add(newProject); @@ -53,7 +53,7 @@ qx.Class.define("osparc.product.quickStart.s4llite.Dashboard", { this._add(otherProjects); const otherProjects2Text = this.tr("\ - 3) TUTORIALS: A set of pre-built read-only tutorial projects with results is available to all S4Llite users. When a tutorial is selected, a \ + 3) TUTORIALS: A set of pre-built read-only tutorial projects with results is available to all Sim4Life.lite users. When a tutorial is selected, a \ copy is automatically created and added to the user’s Projects tab. This new copy is editable and can be shared.\ "); const otherProjects2 = osparc.product.quickStart.Utils.createLabel(otherProjects2Text); @@ -68,8 +68,8 @@ qx.Class.define("osparc.product.quickStart.s4llite.Dashboard", { this._add(dashboardTutorials); const importProjectsText = this.tr("\ - 4) To open an existing desktop project in S4Llite: \ - - Click the + Start S4Llite button to create a new project.
\ + 4) To open an existing desktop project in Sim4Life.lite: \ + - Click the + Start Sim4Life.lite button to create a new project.
\ - Click the menu and select “File Browser…”.
\ - Click “Upload File” for the .smash project and select the file from your desktop. Repeat the same step, but this \ time select “Upload Folder” and then select the result folder from your desktop. Close the window
\ diff --git a/services/static-webserver/client/source/class/osparc/product/quickStart/s4llite/S4LLiteSpecs.js b/services/static-webserver/client/source/class/osparc/product/quickStart/s4llite/S4LLiteSpecs.js index 4b605b8c694..fcdd411c10b 100644 --- a/services/static-webserver/client/source/class/osparc/product/quickStart/s4llite/S4LLiteSpecs.js +++ b/services/static-webserver/client/source/class/osparc/product/quickStart/s4llite/S4LLiteSpecs.js @@ -19,23 +19,23 @@ qx.Class.define("osparc.product.quickStart.s4llite.S4LLiteSpecs", { extend: osparc.product.quickStart.SlideBase, construct: function() { - const title = this.tr("S4Llite: Features and Limitations"); + const title = this.tr("Sim4Life.lite: Features and Limitations"); this.base(arguments, title); }, members: { _populateCard: function() { const introText = this.tr("\ - S4Llite is a powerful web-based simulation platform that allows you to model and analyze real-world phenomena and to \ - design complex technical devices in a validated environment. S4Llite has been created specifically for students to \ + Sim4Life.lite is a powerful web-based simulation platform that allows you to model and analyze real-world phenomena and to \ + design complex technical devices in a validated environment. Sim4Life.lite has been created specifically for students to \ facilitate their understanding of computational modeling and simulations for various topics, ranging from wireless communication \ - to medical applications. The access to S4Llite is available free of charge to students enrolled at registered universities.\ + to medical applications. The access to Sim4Life.lite is available free of charge to students enrolled at registered universities.\ "); const intro = osparc.product.quickStart.Utils.createLabel(introText); this._add(intro); const featuresText = this.tr("\ - S4Llite offers
\ + Sim4Life.lite offers
\ - Framework (GUI, Modeling, Postprocessing)
\ - 3D modeling environment (based on the ACIS toolkit) and CAD translators
\ - Postprocessing and visualization of the simulation results (2D and 3D viewers, 2D planar slice, volume rendering, streamlines, surface fields on arbitrary 3D structures, radiation and far-field data)
\ diff --git a/services/static-webserver/client/source/class/osparc/product/quickStart/s4llite/S4LLiteUI.js b/services/static-webserver/client/source/class/osparc/product/quickStart/s4llite/S4LLiteUI.js index 59c2d0c81e7..09e29fc108a 100644 --- a/services/static-webserver/client/source/class/osparc/product/quickStart/s4llite/S4LLiteUI.js +++ b/services/static-webserver/client/source/class/osparc/product/quickStart/s4llite/S4LLiteUI.js @@ -19,14 +19,14 @@ qx.Class.define("osparc.product.quickStart.s4llite.S4LLiteUI", { extend: osparc.product.quickStart.SlideBase, construct: function() { - const title = this.tr("S4Llite"); + const title = this.tr("Sim4Life.lite"); this.base(arguments, title); }, members: { _populateCard: function() { const introText = this.tr("\ - To check the S4Llite manual, please open a project and access the documentation via Help in the menu as shown below. Enjoy!\ + To check the Sim4Life.lite manual, please open a project and access the documentation via Help in the menu as shown below. Enjoy!\ "); const intro = osparc.product.quickStart.Utils.createLabel(introText); this._add(intro); diff --git a/services/static-webserver/client/source/class/osparc/product/quickStart/s4llite/Welcome.js b/services/static-webserver/client/source/class/osparc/product/quickStart/s4llite/Welcome.js index b6816398a2b..77e187a1d8c 100644 --- a/services/static-webserver/client/source/class/osparc/product/quickStart/s4llite/Welcome.js +++ b/services/static-webserver/client/source/class/osparc/product/quickStart/s4llite/Welcome.js @@ -30,13 +30,13 @@ qx.Class.define("osparc.product.quickStart.s4llite.Welcome", { this._add(welcome); const introText = this.tr("\ - This quick user’s guide gives a short introduction to S4Llite. We will show:
\ + This quick user’s guide gives a short introduction to Sim4Life.lite. We will show:
\ - how to get started with a new project,
\ - how to get started from an existing tutorial project
\ - - how to open Sim4Life lite desktop simulation projects in S4Llite,
\ - - S4Llite features, limitations and user interface
\ + - how to open Sim4Life desktop simulation projects in Sim4Life.lite,
\ + - Sim4Life.lite features, limitations and user interface
\
\ - For more specific technical information, please refer to the Dashboard Manual and the S4Llite Manual.\ + For more specific technical information, please refer to the Dashboard Manual and the Sim4Life.lite Manual.\ "); const intro = osparc.product.quickStart.Utils.createLabel(introText); this._add(intro); diff --git a/services/static-webserver/client/source/class/osparc/utils/Utils.js b/services/static-webserver/client/source/class/osparc/utils/Utils.js index a502a5144d0..42db323492d 100644 --- a/services/static-webserver/client/source/class/osparc/utils/Utils.js +++ b/services/static-webserver/client/source/class/osparc/utils/Utils.js @@ -994,12 +994,13 @@ qx.Class.define("osparc.utils.Utils", { getParamFromURL: (urlStr, param) => { const url = new URL(urlStr); - const args = new URLSearchParams(url.search); - return args.get(param); + const urlParams = new URLSearchParams(url.search); + return urlParams.get(param); }, - hasParamFromURL: (url, param) => { - const urlParams = new URLSearchParams(url); + hasParamFromURL: (urlStr, param) => { + const url = new URL(urlStr); + const urlParams = new URLSearchParams(url.search); return urlParams.has(param); }, diff --git a/services/static-webserver/client/source/class/osparc/viewer/NodeViewer.js b/services/static-webserver/client/source/class/osparc/viewer/NodeViewer.js index 94aeb50ef5f..57d97839dc7 100644 --- a/services/static-webserver/client/source/class/osparc/viewer/NodeViewer.js +++ b/services/static-webserver/client/source/class/osparc/viewer/NodeViewer.js @@ -79,7 +79,7 @@ qx.Class.define("osparc.viewer.NodeViewer", { const iframeHandler = node.getIframeHandler(); if (iframeHandler) { - iframeHandler.startPolling(); + iframeHandler.checkState(); iframeHandler.addListener("iframeChanged", () => this.__iFrameChanged(), this); iframeHandler.getIFrame().addListener("load", () => this.__iFrameChanged(), this); this.__iFrameChanged(); diff --git a/services/static-webserver/client/source/resource/osparc/new_studies.json b/services/static-webserver/client/source/resource/osparc/new_studies.json index bd56ab64a2a..cac8acd2f8f 100644 --- a/services/static-webserver/client/source/resource/osparc/new_studies.json +++ b/services/static-webserver/client/source/resource/osparc/new_studies.json @@ -140,7 +140,7 @@ "linkedResource": "services", "resources": [{ "expectedKey": "simcore/services/dynamic/sim4life-lite", - "title": "Start S4Llite", + "title": "Start ${replace_me_product_name}", "description": "New project", "newStudyLabel": "New project", "idToWidget": "startS4LButton"