From 9a186633111659278b049f5e02cce03a5a4d2088 Mon Sep 17 00:00:00 2001 From: odeimaiz Date: Fri, 4 Jul 2025 17:34:48 +0200 Subject: [PATCH 1/8] reload button --- .../class/osparc/jobs/ActivityCenterWindow.js | 1 - .../source/class/osparc/jobs/RunsBrowser.js | 26 +++++++++---------- 2 files changed, 13 insertions(+), 14 deletions(-) diff --git a/services/static-webserver/client/source/class/osparc/jobs/ActivityCenterWindow.js b/services/static-webserver/client/source/class/osparc/jobs/ActivityCenterWindow.js index 692934925858..d374a28f99b6 100644 --- a/services/static-webserver/client/source/class/osparc/jobs/ActivityCenterWindow.js +++ b/services/static-webserver/client/source/class/osparc/jobs/ActivityCenterWindow.js @@ -72,7 +72,6 @@ qx.Class.define("osparc.jobs.ActivityCenterWindow", { }); this.addListener("close", () => { - runsBrowser.stopInterval(); subRunsBrowser.stopInterval(); }); }, diff --git a/services/static-webserver/client/source/class/osparc/jobs/RunsBrowser.js b/services/static-webserver/client/source/class/osparc/jobs/RunsBrowser.js index c5ab4355df94..2636961004da 100644 --- a/services/static-webserver/client/source/class/osparc/jobs/RunsBrowser.js +++ b/services/static-webserver/client/source/class/osparc/jobs/RunsBrowser.js @@ -24,6 +24,8 @@ qx.Class.define("osparc.jobs.RunsBrowser", { this._setLayout(new qx.ui.layout.VBox(10)); + const reloadButton = this.getChildControl("reload-button"); + reloadButton.addListener("execute", () => this.reloadRuns()); this.getChildControl("intro-label"); const jobsFilter = this.getChildControl("jobs-filter"); const runningCB = this.getChildControl("running-only-cb"); @@ -35,8 +37,6 @@ qx.Class.define("osparc.jobs.RunsBrowser", { }); runningCB.bind("value", runsTable, "runningOnly"); - - this.__reloadInterval = setInterval(() => this.reloadRuns(), 10*1000); }, events: { @@ -49,13 +49,19 @@ qx.Class.define("osparc.jobs.RunsBrowser", { _createChildControlImpl: function(id) { let control; switch (id) { - case "header-filter": + case "header-toolbar": control = new qx.ui.container.Composite(new qx.ui.layout.HBox(5)); this._add(control); break; + case "reload-button": + control = new qx.ui.form.Button(this.tr("Reload"), "@FontAwesome5Solid/sync-alt/14"); + this.getChildControl("header-toolbar").add(control); + break; case "intro-label": - control = new qx.ui.basic.Label(this.tr("Select a Run to check the details")); - this.getChildControl("header-filter").add(control); + control = new qx.ui.basic.Label(this.tr("Select a Run to check the details")).set({ + alignY: "middle", + }); + this.getChildControl("header-toolbar").add(control); break; case "jobs-filter": control = new osparc.filter.TextFilter("text", "jobsList").set({ @@ -66,7 +72,7 @@ qx.Class.define("osparc.jobs.RunsBrowser", { placeholder: qx.locale.Manager.tr("Filter by name or ID"), }); control.hide(); // @matusdrobuliak66: remove this when the backend is ready - this.getChildControl("header-filter").add(control, { + this.getChildControl("header-toolbar").add(control, { flex: 1 }); break; @@ -75,7 +81,7 @@ qx.Class.define("osparc.jobs.RunsBrowser", { value: true, label: qx.locale.Manager.tr("Active only"), }); - this.getChildControl("header-filter").add(control); + this.getChildControl("header-toolbar").add(control); break; case "runs-table": { const projectUuid = null; @@ -95,11 +101,5 @@ qx.Class.define("osparc.jobs.RunsBrowser", { const runsTable = this.getChildControl("runs-table"); runsTable.reloadRuns(); }, - - stopInterval: function() { - if (this.__reloadInterval) { - clearInterval(this.__reloadInterval); - } - }, } }) From 5c0b44af1fbf8d8ae57aa30d775ef31ef4137148 Mon Sep 17 00:00:00 2001 From: odeimaiz Date: Fri, 4 Jul 2025 17:36:15 +0200 Subject: [PATCH 2/8] SERVER_MAX_LIMIT from jobs --- .../client/source/class/osparc/jobs/RunsTableModel.js | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/services/static-webserver/client/source/class/osparc/jobs/RunsTableModel.js b/services/static-webserver/client/source/class/osparc/jobs/RunsTableModel.js index f11bb85e402c..2d12c4bac636 100644 --- a/services/static-webserver/client/source/class/osparc/jobs/RunsTableModel.js +++ b/services/static-webserver/client/source/class/osparc/jobs/RunsTableModel.js @@ -79,10 +79,6 @@ qx.Class.define("osparc.jobs.RunsTableModel", { }, }, - statics: { - SERVER_MAX_LIMIT: 49, - }, - members: { __includeChildren: false, @@ -153,14 +149,15 @@ qx.Class.define("osparc.jobs.RunsTableModel", { }; // Divides the model row request into several server requests to comply with the number of rows server limit + const serverMaxLimit = osparc.store.Jobs.SERVER_MAX_LIMIT; const reqLimit = lastRow - firstRow + 1; // Number of requested rows - let nRequests = Math.ceil(reqLimit / this.self().SERVER_MAX_LIMIT); + let nRequests = Math.ceil(reqLimit / serverMaxLimit); if (nRequests > 1) { const requests = []; - for (let i=firstRow; i <= lastRow; i += this.self().SERVER_MAX_LIMIT) { + for (let i=firstRow; i <= lastRow; i += serverMaxLimit) { // fetch the first page only if (i < 1) { - requests.push(getFetchPromise(i, i > lastRow - this.self().SERVER_MAX_LIMIT + 1 ? reqLimit % this.self().SERVER_MAX_LIMIT : this.self().SERVER_MAX_LIMIT)) + requests.push(getFetchPromise(i, i > lastRow - serverMaxLimit + 1 ? reqLimit % serverMaxLimit : serverMaxLimit)) } } Promise.all(requests) From ec5045673a58e0946314f2819a7e483e32487c81 Mon Sep 17 00:00:00 2001 From: odeimaiz Date: Fri, 4 Jul 2025 17:36:31 +0200 Subject: [PATCH 3/8] minor --- .../client/source/class/osparc/jobs/RunsTableModel.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/static-webserver/client/source/class/osparc/jobs/RunsTableModel.js b/services/static-webserver/client/source/class/osparc/jobs/RunsTableModel.js index 2d12c4bac636..2c0bdc788f44 100644 --- a/services/static-webserver/client/source/class/osparc/jobs/RunsTableModel.js +++ b/services/static-webserver/client/source/class/osparc/jobs/RunsTableModel.js @@ -80,7 +80,7 @@ qx.Class.define("osparc.jobs.RunsTableModel", { }, members: { - __includeChildren: false, + __includeChildren: null, // overridden sortByColumn(columnIndex, ascending) { From 9b2e0d56bda352cdd880aa7f4a58b4015a2c1cdf Mon Sep 17 00:00:00 2001 From: odeimaiz Date: Fri, 4 Jul 2025 17:36:50 +0200 Subject: [PATCH 4/8] fix --- .../client/source/class/osparc/jobs/RunsTableModel.js | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/services/static-webserver/client/source/class/osparc/jobs/RunsTableModel.js b/services/static-webserver/client/source/class/osparc/jobs/RunsTableModel.js index 2c0bdc788f44..017a04277ed2 100644 --- a/services/static-webserver/client/source/class/osparc/jobs/RunsTableModel.js +++ b/services/static-webserver/client/source/class/osparc/jobs/RunsTableModel.js @@ -155,10 +155,7 @@ qx.Class.define("osparc.jobs.RunsTableModel", { if (nRequests > 1) { const requests = []; for (let i=firstRow; i <= lastRow; i += serverMaxLimit) { - // fetch the first page only - if (i < 1) { - requests.push(getFetchPromise(i, i > lastRow - serverMaxLimit + 1 ? reqLimit % serverMaxLimit : serverMaxLimit)) - } + requests.push(getFetchPromise(i, i > lastRow - serverMaxLimit + 1 ? reqLimit % serverMaxLimit : serverMaxLimit)); } Promise.all(requests) .then(responses => this._onRowDataLoaded(responses.flat())) From c72a59c08f6523a4628ac0f4d869fce07d1906f1 Mon Sep 17 00:00:00 2001 From: odeimaiz Date: Fri, 4 Jul 2025 17:37:19 +0200 Subject: [PATCH 5/8] faster tooltip --- .../client/source/class/osparc/theme/Appearance.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/services/static-webserver/client/source/class/osparc/theme/Appearance.js b/services/static-webserver/client/source/class/osparc/theme/Appearance.js index c0a1a3da81ce..2dcb2db7d46f 100644 --- a/services/static-webserver/client/source/class/osparc/theme/Appearance.js +++ b/services/static-webserver/client/source/class/osparc/theme/Appearance.js @@ -1192,8 +1192,8 @@ qx.Theme.define("osparc.theme.Appearance", { padding: [5, 10], // showTimeout is themeable so it can be tuned // it was defaulted to 700 which was too short - showTimeout: 2000, - hideTimeout: 6000, + showTimeout: 1400, + hideTimeout: 5000, }) }, From c1bf0365e9df2d5235b2b9ce24c3ea631946a3a1 Mon Sep 17 00:00:00 2001 From: odeimaiz Date: Fri, 4 Jul 2025 17:38:01 +0200 Subject: [PATCH 6/8] imageCache for button --- .../table/cellrenderer/ImageButtonRenderer.js | 38 ++++++++++++++++++- 1 file changed, 36 insertions(+), 2 deletions(-) diff --git a/services/static-webserver/client/source/class/osparc/ui/table/cellrenderer/ImageButtonRenderer.js b/services/static-webserver/client/source/class/osparc/ui/table/cellrenderer/ImageButtonRenderer.js index 8b9fd7896bd4..43cfd6b8b055 100644 --- a/services/static-webserver/client/source/class/osparc/ui/table/cellrenderer/ImageButtonRenderer.js +++ b/services/static-webserver/client/source/class/osparc/ui/table/cellrenderer/ImageButtonRenderer.js @@ -21,6 +21,8 @@ qx.Class.define("osparc.ui.table.cellrenderer.ImageButtonRenderer", { construct: function(clickAction, iconPath) { this.base(arguments, clickAction); + this.__imageCache = {}; + this.setIconPath(iconPath); }, @@ -34,11 +36,43 @@ qx.Class.define("osparc.ui.table.cellrenderer.ImageButtonRenderer", { }, members: { + __imageCache: null, + __applyIconPath: function(iconPath) { const resMgr = qx.util.ResourceManager.getInstance(); - const iconUrl = resMgr.toUri(iconPath); // Resolves to the correct URL of the asset + const iconUrl = resMgr.toUri(iconPath); + + // Create a data URI or use a more cache-friendly approach + // Use base64 encoding for small icons (best for caching) + this.__loadImageAsDataUri(iconUrl, iconPath); + }, + + __loadImageAsDataUri: function(iconUrl, iconPath) { + if (this.__imageCache[iconPath]) { + this.setButtonContent(this.__imageCache[iconPath]); + return; + } + + // Fetch and convert to data URI for permanent caching + fetch(iconUrl) + .then(response => response.blob()) + .then(blob => { + const reader = new FileReader(); + reader.onload = () => { + const dataUri = reader.result; + const content = `icon`; - this.setButtonContent(`icon`); + // Cache the data URI + this.__imageCache[iconPath] = content; + this.setButtonContent(content); + }; + reader.readAsDataURL(blob); + }) + .catch(err => { + console.warn("Failed to cache icon as data URI:", iconPath, err); + // Fallback to original method + this.setButtonContent(`icon`); + }); }, } }); From 0b8aaaaf129a9443e105300889d97555fbb5bc5e Mon Sep 17 00:00:00 2001 From: odeimaiz Date: Fri, 4 Jul 2025 17:40:00 +0200 Subject: [PATCH 7/8] minor --- .../client/source/class/osparc/jobs/RunsTableModel.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/static-webserver/client/source/class/osparc/jobs/RunsTableModel.js b/services/static-webserver/client/source/class/osparc/jobs/RunsTableModel.js index 017a04277ed2..1e620708b1bc 100644 --- a/services/static-webserver/client/source/class/osparc/jobs/RunsTableModel.js +++ b/services/static-webserver/client/source/class/osparc/jobs/RunsTableModel.js @@ -122,7 +122,7 @@ qx.Class.define("osparc.jobs.RunsTableModel", { const lastRow = Math.min(qxLastRow, this._rowCount - 1); // Returns a request promise with given offset and limit const getFetchPromise = (offset, limit) => { - const orderBy = this.getOrderBy(); + const orderBy = this.getOrderBy(); let promise; if (this.getProjectUuid()) { promise = osparc.store.Jobs.getInstance().fetchJobsHistory(this.getProjectUuid(), this.__includeChildren, offset, limit, orderBy); From 77a1b4f5cbc47fcd9ad9cb61f29d91657175e74d Mon Sep 17 00:00:00 2001 From: odeimaiz Date: Fri, 4 Jul 2025 18:04:18 +0200 Subject: [PATCH 8/8] minor --- .../source/class/osparc/jobs/SubRunsTableModel.js | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/services/static-webserver/client/source/class/osparc/jobs/SubRunsTableModel.js b/services/static-webserver/client/source/class/osparc/jobs/SubRunsTableModel.js index 2c43fa59ed95..58ad6040cfb3 100644 --- a/services/static-webserver/client/source/class/osparc/jobs/SubRunsTableModel.js +++ b/services/static-webserver/client/source/class/osparc/jobs/SubRunsTableModel.js @@ -57,10 +57,6 @@ qx.Class.define("osparc.jobs.SubRunsTableModel", { }, }, - statics: { - SERVER_MAX_LIMIT: 49, - }, - members: { // overridden sortByColumn(columnIndex, ascending) { @@ -132,12 +128,13 @@ qx.Class.define("osparc.jobs.SubRunsTableModel", { }; // Divides the model row request into several server requests to comply with the number of rows server limit + const serverMaxLimit = osparc.store.Jobs.SERVER_MAX_LIMIT; const reqLimit = lastRow - firstRow + 1; // Number of requested rows - const nRequests = Math.ceil(reqLimit / this.self().SERVER_MAX_LIMIT); + const nRequests = Math.ceil(reqLimit / serverMaxLimit); if (nRequests > 1) { const requests = []; - for (let i=firstRow; i <= lastRow; i += this.self().SERVER_MAX_LIMIT) { - requests.push(getFetchPromise(i, i > lastRow - this.self().SERVER_MAX_LIMIT + 1 ? reqLimit % this.self().SERVER_MAX_LIMIT : this.self().SERVER_MAX_LIMIT)) + for (let i=firstRow; i <= lastRow; i += serverMaxLimit) { + requests.push(getFetchPromise(i, i > lastRow - serverMaxLimit + 1 ? reqLimit % serverMaxLimit : serverMaxLimit)) } Promise.all(requests) .then(responses => this._onRowDataLoaded(responses.flat()))