From 807257d1e5c0cee54e4e5c2f3a8bcfcbe65ebc70 Mon Sep 17 00:00:00 2001 From: odeimaiz Date: Tue, 13 May 2025 13:09:13 +0200 Subject: [PATCH 01/22] cancel image --- .../client/source/resource/osparc/circle-xmark-text.svg | 1 + 1 file changed, 1 insertion(+) create mode 100644 services/static-webserver/client/source/resource/osparc/circle-xmark-text.svg diff --git a/services/static-webserver/client/source/resource/osparc/circle-xmark-text.svg b/services/static-webserver/client/source/resource/osparc/circle-xmark-text.svg new file mode 100644 index 000000000000..134422e82d53 --- /dev/null +++ b/services/static-webserver/client/source/resource/osparc/circle-xmark-text.svg @@ -0,0 +1 @@ + From 777669f617024c6810632752c2b819f3a8453835 Mon Sep 17 00:00:00 2001 From: odeimaiz Date: Tue, 13 May 2025 13:11:11 +0200 Subject: [PATCH 02/22] cancel button --- .../client/source/class/osparc/jobs/RunsTable.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/services/static-webserver/client/source/class/osparc/jobs/RunsTable.js b/services/static-webserver/client/source/class/osparc/jobs/RunsTable.js index 41fc06821a0c..eafba3c90cfa 100644 --- a/services/static-webserver/client/source/class/osparc/jobs/RunsTable.js +++ b/services/static-webserver/client/source/class/osparc/jobs/RunsTable.js @@ -36,9 +36,9 @@ qx.Class.define("osparc.jobs.RunsTable", { Object.values(this.self().COLS).forEach(col => columnModel.setColumnWidth(col.column, col.width)); - const iconPathStop = "osparc/circle-stop-text.svg"; - const fontButtonRendererStop = new osparc.ui.table.cellrenderer.ImageButtonRenderer("stop", iconPathStop); - columnModel.setDataCellRenderer(this.self().COLS.ACTION_STOP.column, fontButtonRendererStop); + const iconPathStop = "osparc/circle-xmark-text.svg"; + const fontButtonRendererStop = new osparc.ui.table.cellrenderer.ImageButtonRenderer("cancel", iconPathStop); + columnModel.setDataCellRenderer(this.self().COLS.ACTION_CANCEL.column, fontButtonRendererStop); this.__attachHandlers(); }, @@ -89,8 +89,8 @@ qx.Class.define("osparc.jobs.RunsTable", { width: 130, sortable: true }, - ACTION_STOP: { - id: "action_stop", + ACTION_CANCEL: { + id: "action_cancel", column: 6, label: "", width: 40 From 2ef9c7fb920583e18b73bc4bae4259bdcad83250 Mon Sep 17 00:00:00 2001 From: odeimaiz Date: Tue, 13 May 2025 13:13:22 +0200 Subject: [PATCH 03/22] move to icons --- .../client/source/class/osparc/jobs/RunsTable.js | 2 +- .../client/source/class/osparc/jobs/SubRunsTable.js | 4 ++-- .../client/source/class/osparc/widget/logger/LoggerModel.js | 6 +++--- .../client/source/resource/osparc/circle-stop-text.svg | 1 - .../osparc/{ => icons}/circle-exclamation-solid.svg | 2 +- .../resource/osparc/{ => icons}/circle-info-solid.svg | 2 +- .../source/resource/osparc/{ => icons}/circle-info-text.svg | 2 +- .../resource/osparc/{ => icons}/circle-xmark-solid.svg | 2 +- .../resource/osparc/{ => icons}/circle-xmark-text.svg | 0 .../client/source/resource/osparc/{ => icons}/logs-text.svg | 2 +- .../client/source/resource/osparc/trash-text.svg | 1 - 11 files changed, 11 insertions(+), 13 deletions(-) delete mode 100644 services/static-webserver/client/source/resource/osparc/circle-stop-text.svg rename services/static-webserver/client/source/resource/osparc/{ => icons}/circle-exclamation-solid.svg (87%) rename services/static-webserver/client/source/resource/osparc/{ => icons}/circle-info-solid.svg (87%) rename services/static-webserver/client/source/resource/osparc/{ => icons}/circle-info-text.svg (87%) rename services/static-webserver/client/source/resource/osparc/{ => icons}/circle-xmark-solid.svg (97%) rename services/static-webserver/client/source/resource/osparc/{ => icons}/circle-xmark-text.svg (100%) rename services/static-webserver/client/source/resource/osparc/{ => icons}/logs-text.svg (96%) delete mode 100644 services/static-webserver/client/source/resource/osparc/trash-text.svg diff --git a/services/static-webserver/client/source/class/osparc/jobs/RunsTable.js b/services/static-webserver/client/source/class/osparc/jobs/RunsTable.js index eafba3c90cfa..f6445171bb02 100644 --- a/services/static-webserver/client/source/class/osparc/jobs/RunsTable.js +++ b/services/static-webserver/client/source/class/osparc/jobs/RunsTable.js @@ -36,7 +36,7 @@ qx.Class.define("osparc.jobs.RunsTable", { Object.values(this.self().COLS).forEach(col => columnModel.setColumnWidth(col.column, col.width)); - const iconPathStop = "osparc/circle-xmark-text.svg"; + const iconPathStop = "osparc/icons/circle-xmark-text.svg"; const fontButtonRendererStop = new osparc.ui.table.cellrenderer.ImageButtonRenderer("cancel", iconPathStop); columnModel.setDataCellRenderer(this.self().COLS.ACTION_CANCEL.column, fontButtonRendererStop); diff --git a/services/static-webserver/client/source/class/osparc/jobs/SubRunsTable.js b/services/static-webserver/client/source/class/osparc/jobs/SubRunsTable.js index 2f457bb3efbb..e79de0315a5b 100644 --- a/services/static-webserver/client/source/class/osparc/jobs/SubRunsTable.js +++ b/services/static-webserver/client/source/class/osparc/jobs/SubRunsTable.js @@ -37,11 +37,11 @@ qx.Class.define("osparc.jobs.SubRunsTable", { Object.values(this.self().COLS).forEach(col => columnModel.setColumnWidth(col.column, col.width)); - const iconPathInfo = "osparc/circle-info-text.svg"; + const iconPathInfo = "osparc/icons/circle-info-text.svg"; const fontButtonRendererInfo = new osparc.ui.table.cellrenderer.ImageButtonRenderer("info", iconPathInfo); columnModel.setDataCellRenderer(this.self().COLS.INFO.column, fontButtonRendererInfo); - const iconPathLogs = "osparc/logs-text.svg"; + const iconPathLogs = "osparc/icons/logs-text.svg"; const fontButtonRendererLogs = new osparc.ui.table.cellrenderer.ImageButtonRenderer("logs", iconPathLogs); columnModel.setDataCellRenderer(this.self().COLS.LOGS.column, fontButtonRendererLogs); diff --git a/services/static-webserver/client/source/class/osparc/widget/logger/LoggerModel.js b/services/static-webserver/client/source/class/osparc/widget/logger/LoggerModel.js index edca2766438e..953c4448cafb 100644 --- a/services/static-webserver/client/source/class/osparc/widget/logger/LoggerModel.js +++ b/services/static-webserver/client/source/class/osparc/widget/logger/LoggerModel.js @@ -83,13 +83,13 @@ qx.Class.define("osparc.widget.logger.LoggerModel", { let iconSource = ""; switch (logLevel) { case logLevels.INFO: - iconSource = "osparc/circle-info-solid.svg"; + iconSource = "osparc/icons/circle-info-solid.svg"; break; case logLevels.WARNING: - iconSource = "osparc/circle-exclamation-solid.svg"; + iconSource = "osparc/icons/circle-exclamation-solid.svg"; break; case logLevels.ERROR: - iconSource = "osparc/circle-xmark-solid.svg"; + iconSource = "osparc/icons/circle-xmark-solid.svg"; break; } return iconSource; diff --git a/services/static-webserver/client/source/resource/osparc/circle-stop-text.svg b/services/static-webserver/client/source/resource/osparc/circle-stop-text.svg deleted file mode 100644 index 1470fd0f2952..000000000000 --- a/services/static-webserver/client/source/resource/osparc/circle-stop-text.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/services/static-webserver/client/source/resource/osparc/circle-exclamation-solid.svg b/services/static-webserver/client/source/resource/osparc/icons/circle-exclamation-solid.svg similarity index 87% rename from services/static-webserver/client/source/resource/osparc/circle-exclamation-solid.svg rename to services/static-webserver/client/source/resource/osparc/icons/circle-exclamation-solid.svg index fa80fe70833c..8f3a586bfa80 100644 --- a/services/static-webserver/client/source/resource/osparc/circle-exclamation-solid.svg +++ b/services/static-webserver/client/source/resource/osparc/icons/circle-exclamation-solid.svg @@ -1 +1 @@ - \ No newline at end of file + diff --git a/services/static-webserver/client/source/resource/osparc/circle-info-solid.svg b/services/static-webserver/client/source/resource/osparc/icons/circle-info-solid.svg similarity index 87% rename from services/static-webserver/client/source/resource/osparc/circle-info-solid.svg rename to services/static-webserver/client/source/resource/osparc/icons/circle-info-solid.svg index 64e1e26721a3..5e28757f57f6 100644 --- a/services/static-webserver/client/source/resource/osparc/circle-info-solid.svg +++ b/services/static-webserver/client/source/resource/osparc/icons/circle-info-solid.svg @@ -1 +1 @@ - \ No newline at end of file + diff --git a/services/static-webserver/client/source/resource/osparc/circle-info-text.svg b/services/static-webserver/client/source/resource/osparc/icons/circle-info-text.svg similarity index 87% rename from services/static-webserver/client/source/resource/osparc/circle-info-text.svg rename to services/static-webserver/client/source/resource/osparc/icons/circle-info-text.svg index b753c59738b3..5b80476aa3a4 100644 --- a/services/static-webserver/client/source/resource/osparc/circle-info-text.svg +++ b/services/static-webserver/client/source/resource/osparc/icons/circle-info-text.svg @@ -1 +1 @@ - \ No newline at end of file + diff --git a/services/static-webserver/client/source/resource/osparc/circle-xmark-solid.svg b/services/static-webserver/client/source/resource/osparc/icons/circle-xmark-solid.svg similarity index 97% rename from services/static-webserver/client/source/resource/osparc/circle-xmark-solid.svg rename to services/static-webserver/client/source/resource/osparc/icons/circle-xmark-solid.svg index e7074e6aadf9..2844d4d2e155 100644 --- a/services/static-webserver/client/source/resource/osparc/circle-xmark-solid.svg +++ b/services/static-webserver/client/source/resource/osparc/icons/circle-xmark-solid.svg @@ -1 +1 @@ - \ No newline at end of file + diff --git a/services/static-webserver/client/source/resource/osparc/circle-xmark-text.svg b/services/static-webserver/client/source/resource/osparc/icons/circle-xmark-text.svg similarity index 100% rename from services/static-webserver/client/source/resource/osparc/circle-xmark-text.svg rename to services/static-webserver/client/source/resource/osparc/icons/circle-xmark-text.svg diff --git a/services/static-webserver/client/source/resource/osparc/logs-text.svg b/services/static-webserver/client/source/resource/osparc/icons/logs-text.svg similarity index 96% rename from services/static-webserver/client/source/resource/osparc/logs-text.svg rename to services/static-webserver/client/source/resource/osparc/icons/logs-text.svg index 20dd82103ce4..115dfe4b2655 100644 --- a/services/static-webserver/client/source/resource/osparc/logs-text.svg +++ b/services/static-webserver/client/source/resource/osparc/icons/logs-text.svg @@ -1 +1 @@ - \ No newline at end of file + diff --git a/services/static-webserver/client/source/resource/osparc/trash-text.svg b/services/static-webserver/client/source/resource/osparc/trash-text.svg deleted file mode 100644 index 0cbfe135be55..000000000000 --- a/services/static-webserver/client/source/resource/osparc/trash-text.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file From 6bb2311538db31fbba1661aa272c134b1113c7f8 Mon Sep 17 00:00:00 2001 From: odeimaiz Date: Tue, 13 May 2025 13:36:33 +0200 Subject: [PATCH 04/22] init STATUS_LABELS mapping --- .../client/source/class/osparc/data/Job.js | 14 +++++++++++++ .../source/class/osparc/jobs/RunsTable.js | 20 ++++++++++++++----- .../class/osparc/jobs/RunsTableModel.js | 2 +- .../source/class/osparc/jobs/SubRunsTable.js | 6 +++--- 4 files changed, 33 insertions(+), 9 deletions(-) diff --git a/services/static-webserver/client/source/class/osparc/data/Job.js b/services/static-webserver/client/source/class/osparc/data/Job.js index 1a143cbff42e..31d8456a0b0a 100644 --- a/services/static-webserver/client/source/class/osparc/data/Job.js +++ b/services/static-webserver/client/source/class/osparc/data/Job.js @@ -81,6 +81,20 @@ qx.Class.define("osparc.data.Job", { }, }, + statics: { + STATUS_LABELS: { + "NOT_STARTED": "Not Started", + "PUBLISHED": "Published", + "PENDING": "Pending", + "RUNNING": "Running", + "SUCCESS": "Success", + "FAILED": "Failed", + "ABORTED": "Aborted", + "WAITING_FOR_RESOURCES": "Waiting for Resources", + "WAITING_FOR_CLUSTER": "Waiting for Cluster", + }, + }, + members: { __subJobs: null, diff --git a/services/static-webserver/client/source/class/osparc/jobs/RunsTable.js b/services/static-webserver/client/source/class/osparc/jobs/RunsTable.js index f6445171bb02..3108bb26a612 100644 --- a/services/static-webserver/client/source/class/osparc/jobs/RunsTable.js +++ b/services/static-webserver/client/source/class/osparc/jobs/RunsTable.js @@ -40,6 +40,10 @@ qx.Class.define("osparc.jobs.RunsTable", { const fontButtonRendererStop = new osparc.ui.table.cellrenderer.ImageButtonRenderer("cancel", iconPathStop); columnModel.setDataCellRenderer(this.self().COLS.ACTION_CANCEL.column, fontButtonRendererStop); + const iconPathInfo = "osparc/icons/circle-info-text.svg"; + const fontButtonRendererInfo = new osparc.ui.table.cellrenderer.ImageButtonRenderer("info", iconPathInfo); + columnModel.setDataCellRenderer(this.self().COLS.ACTION_INFO.column, fontButtonRendererInfo); + this.__attachHandlers(); }, @@ -53,20 +57,20 @@ qx.Class.define("osparc.jobs.RunsTable", { id: "projectUuid", column: 0, label: qx.locale.Manager.tr("Project Id"), - width: 170 + width: 200 }, PROJECT_NAME: { id: "projectName", column: 1, label: qx.locale.Manager.tr("Project"), - width: 170, + width: 150, sortable: true }, STATE: { id: "state", column: 2, label: qx.locale.Manager.tr("Status"), - width: 170 + width: 150 }, SUBMIT: { id: "submit", @@ -92,8 +96,14 @@ qx.Class.define("osparc.jobs.RunsTable", { ACTION_CANCEL: { id: "action_cancel", column: 6, - label: "", - width: 40 + label: qx.locale.Manager.tr("Cancel"), + width: 50 + }, + ACTION_INFO: { + id: "action_info", + column: 7, + label: qx.locale.Manager.tr("Info"), + width: 50 }, } }, 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 cd75159534aa..1f80a5fcb4f7 100644 --- a/services/static-webserver/client/source/class/osparc/jobs/RunsTableModel.js +++ b/services/static-webserver/client/source/class/osparc/jobs/RunsTableModel.js @@ -84,7 +84,7 @@ qx.Class.define("osparc.jobs.RunsTableModel", { data.push({ [jobsCols.PROJECT_UUID.id]: job.getProjectUuid(), [jobsCols.PROJECT_NAME.id]: job.getProjectName(), - [jobsCols.STATE.id]: job.getState(), + [jobsCols.STATE.id]: osparc.data.Job.STATUS_LABELS[job.getState()] || job.getState(), [jobsCols.SUBMIT.id]: job.getSubmittedAt() ? osparc.utils.Utils.formatDateAndTime(job.getSubmittedAt()) : "-", [jobsCols.START.id]: job.getStartedAt() ? osparc.utils.Utils.formatDateAndTime(job.getStartedAt()) : "-", [jobsCols.END.id]: job.getEndedAt() ? osparc.utils.Utils.formatDateAndTime(job.getEndedAt()) : "-", diff --git a/services/static-webserver/client/source/class/osparc/jobs/SubRunsTable.js b/services/static-webserver/client/source/class/osparc/jobs/SubRunsTable.js index e79de0315a5b..ebd64c5eb602 100644 --- a/services/static-webserver/client/source/class/osparc/jobs/SubRunsTable.js +++ b/services/static-webserver/client/source/class/osparc/jobs/SubRunsTable.js @@ -54,19 +54,19 @@ qx.Class.define("osparc.jobs.SubRunsTable", { id: "projectUuid", column: 0, label: qx.locale.Manager.tr("Project Id"), - width: 170 + width: 200 }, NODE_ID: { id: "nodeId", column: 1, label: qx.locale.Manager.tr("Node Id"), - width: 170 + width: 200 }, NODE_NAME: { id: "nodeName", column: 2, label: qx.locale.Manager.tr("Node"), - width: 170 + width: 150 }, APP: { id: "app", From fab000a7ca38eb2ea28913a0c738ebe809e75830 Mon Sep 17 00:00:00 2001 From: odeimaiz Date: Tue, 13 May 2025 13:40:44 +0200 Subject: [PATCH 05/22] aesthetics --- .../client/source/class/osparc/jobs/SubRunsTable.js | 4 ++-- .../client/source/class/osparc/jobs/SubRunsTableModel.js | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/services/static-webserver/client/source/class/osparc/jobs/SubRunsTable.js b/services/static-webserver/client/source/class/osparc/jobs/SubRunsTable.js index ebd64c5eb602..0cac58ee779f 100644 --- a/services/static-webserver/client/source/class/osparc/jobs/SubRunsTable.js +++ b/services/static-webserver/client/source/class/osparc/jobs/SubRunsTable.js @@ -66,13 +66,13 @@ qx.Class.define("osparc.jobs.SubRunsTable", { id: "nodeName", column: 2, label: qx.locale.Manager.tr("Node"), - width: 150 + width: 100 }, APP: { id: "app", column: 3, label: qx.locale.Manager.tr("App"), - width: 150 + width: 100 }, STATE: { id: "state", 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 33f65f03a85d..eeafa9ea2515 100644 --- a/services/static-webserver/client/source/class/osparc/jobs/SubRunsTableModel.js +++ b/services/static-webserver/client/source/class/osparc/jobs/SubRunsTableModel.js @@ -96,7 +96,7 @@ qx.Class.define("osparc.jobs.SubRunsTableModel", { [subJobsCols.NODE_ID.id]: subJob.getNodeId(), [subJobsCols.NODE_NAME.id]: subJob.getNodeName(), [subJobsCols.APP.id]: appName + ":" + displayVersion, - [subJobsCols.STATE.id]: subJob.getState(), + [subJobsCols.STATE.id]: osparc.data.Job.STATUS_LABELS[subJob.getState()] || subJob.getState(), [subJobsCols.PROGRESS.id]: subJob.getProgress() * 100 + "%", [subJobsCols.START.id]: startedAt ? osparc.utils.Utils.formatDateAndTime(startedAt) : "-", [subJobsCols.END.id]: endedAt ? osparc.utils.Utils.formatDateAndTime(endedAt) : "-", From 9776505f0747e2c46cc44358ff22010b17a80e4c Mon Sep 17 00:00:00 2001 From: odeimaiz Date: Tue, 13 May 2025 13:59:54 +0200 Subject: [PATCH 06/22] minor fix --- .../source/class/osparc/dashboard/ResourceBrowserBase.js | 8 ++++++++ 1 file changed, 8 insertions(+) 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 5ff218af4518..8daed6a8036b 100644 --- a/services/static-webserver/client/source/class/osparc/dashboard/ResourceBrowserBase.js +++ b/services/static-webserver/client/source/class/osparc/dashboard/ResourceBrowserBase.js @@ -483,6 +483,10 @@ qx.Class.define("osparc.dashboard.ResourceBrowserBase", { }, _addTaskCard: function(task, cardTitle, cardIcon) { + if (!this._resourcesContainer) { + return null; + } + if (task) { const taskPlaceholders = this._resourcesContainer.getCards().filter(card => osparc.dashboard.ResourceBrowserBase.isCardTaskPlaceholder(card)); if (taskPlaceholders.find(taskPlaceholder => taskPlaceholder.getTask() === task)) { @@ -505,6 +509,10 @@ qx.Class.define("osparc.dashboard.ResourceBrowserBase", { }, _removeTaskCard: function(task) { + if (!this._resourcesContainer) { + return; + } + if (task) { const taskPlaceholders = this._resourcesContainer.getCards().filter(card => osparc.dashboard.ResourceBrowserBase.isCardTaskPlaceholder(card)); const taskCard = taskPlaceholders.find(taskPlaceholder => taskPlaceholder.getTask() === task); From 3bd7f4a2a1d756e1648ae13670ee5d293edef7e5 Mon Sep 17 00:00:00 2001 From: odeimaiz Date: Tue, 13 May 2025 14:07:10 +0200 Subject: [PATCH 07/22] osparcCredits --- .../static-webserver/client/source/class/osparc/data/SubJob.js | 2 +- .../client/source/class/osparc/jobs/SubRunsTable.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/services/static-webserver/client/source/class/osparc/data/SubJob.js b/services/static-webserver/client/source/class/osparc/data/SubJob.js index 6642827635a5..7b7cbfd51e9a 100644 --- a/services/static-webserver/client/source/class/osparc/data/SubJob.js +++ b/services/static-webserver/client/source/class/osparc/data/SubJob.js @@ -29,7 +29,7 @@ qx.Class.define("osparc.data.SubJob", { progress: subJobData["progress"], startedAt: subJobData["startedAt"] ? new Date(subJobData["startedAt"]) : null, endedAt: subJobData["endedAt"] ? new Date(subJobData["endedAt"]) : null, - osparcCredits: subJobData["osparcCredits"] || null, + osparcCredits: subJobData["osparcCredits"] === null ? null : -1*parseFloat(subJobData["osparcCredits"]), image: subJobData["image"] || {}, logDownloadLink: subJobData["logDownloadLink"] || null, }); diff --git a/services/static-webserver/client/source/class/osparc/jobs/SubRunsTable.js b/services/static-webserver/client/source/class/osparc/jobs/SubRunsTable.js index 0cac58ee779f..1c4b2e7f95cf 100644 --- a/services/static-webserver/client/source/class/osparc/jobs/SubRunsTable.js +++ b/services/static-webserver/client/source/class/osparc/jobs/SubRunsTable.js @@ -108,7 +108,7 @@ qx.Class.define("osparc.jobs.SubRunsTable", { id: "credits", column: 9, label: qx.locale.Manager.tr("Credits"), - width: 70 + width: 50 }, INFO: { id: "info", From c4ed47bdaceb7b4ff702142b46c2891ac44a1211 Mon Sep 17 00:00:00 2001 From: odeimaiz Date: Tue, 13 May 2025 14:18:06 +0200 Subject: [PATCH 08/22] refactor --- .../source/class/osparc/data/Resources.js | 9 ++ .../class/osparc/desktop/StudyEditor.js | 82 +++++++++---------- 2 files changed, 50 insertions(+), 41 deletions(-) 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 f91a8a5062f4..03547ba470f2 100644 --- a/services/static-webserver/client/source/class/osparc/data/Resources.js +++ b/services/static-webserver/client/source/class/osparc/data/Resources.js @@ -334,6 +334,15 @@ qx.Class.define("osparc.data.Resources", { }, } }, + "runPipeline": { + useCache: false, + endpoints: { + startPipeline: { + method: "POST", + url: statics.API + "/computations/{studyId}:start" + }, + } + }, "jobs": { useCache: false, // handled in osparc.store.Jobs endpoints: { 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 eaae2e78fb35..0a909d80d3f1 100644 --- a/services/static-webserver/client/source/class/osparc/desktop/StudyEditor.js +++ b/services/static-webserver/client/source/class/osparc/desktop/StudyEditor.js @@ -569,64 +569,64 @@ qx.Class.define("osparc.desktop.StudyEditor", { return; } - this.getStudy().setPipelineRunning(true); this.updateStudyDocument() .then(() => { this.__requestStartPipeline(this.getStudy().getUuid(), partialPipeline); }) .catch(() => { this.getStudyLogger().error(null, "Run failed"); - this.getStudy().setPipelineRunning(false); }); }, __requestStartPipeline: function(studyId, partialPipeline = [], forceRestart = false) { - const url = "/computations/" + encodeURIComponent(studyId) + ":start"; - const req = new osparc.io.request.ApiRequest(url, "POST"); - req.addListener("success", this.__onPipelineSubmitted, this); - req.addListener("error", () => { - this.getStudyLogger().error(null, "Error submitting pipeline"); - this.getStudy().setPipelineRunning(false); - }, this); - req.addListener("fail", async e => { - if (e.getTarget().getStatus() == "409") { - this.getStudyLogger().error(null, "Pipeline is already running"); - } else if (e.getTarget().getStatus() == "422") { - this.getStudyLogger().info(null, "The pipeline is up-to-date"); - const msg = this.tr("The pipeline is up-to-date. Do you want to re-run it?"); - const win = new osparc.ui.window.Confirmation(msg).set({ - caption: this.tr("Re-run"), - confirmText: this.tr("Run"), - confirmAction: "create" - }); - win.center(); - win.open(); - win.addListener("close", () => { - if (win.getConfirmed()) { - this.__requestStartPipeline(studyId, partialPipeline, true); - } - }, this); - } else if (e.getTarget().getStatus() == "402") { - const msg = await e.getTarget().getResponse().error.errors[0].message; - osparc.FlashMessenger.logAs(msg, "WARNING"); - } else { - this.getStudyLogger().error(null, "Unsuccessful pipeline submission"); - } - this.getStudy().setPipelineRunning(false); - }, this); + this.getStudy().setPipelineRunning(true); - const requestData = { - "subgraph": partialPipeline, - "force_restart": forceRestart - }; - req.setRequestData(requestData); - req.send(); if (partialPipeline.length) { this.getStudyLogger().info(null, "Starting partial pipeline"); } else { this.getStudyLogger().info(null, "Starting pipeline"); } + const params = { + url: { + "studyId": studyId + }, + data: { + "subgraph": partialPipeline, + "force_restart": forceRestart, + } + }; + osparc.data.Resources.fetch("runPipeline", "startPipeline", params) + .then(() => this.__onPipelineSubmitted) + .catch(err => { + let msg = err.message; + const errStatus = err.status; + if (errStatus == "409") { + this.getStudyLogger().error(null, "Pipeline is already running"); + } else if (errStatus == "422") { + this.getStudyLogger().info(null, "The pipeline is up-to-date"); + msg = this.tr("The pipeline is up-to-date. Do you want to re-run it?"); + const win = new osparc.ui.window.Confirmation(msg).set({ + caption: this.tr("Re-run"), + confirmText: this.tr("Run"), + confirmAction: "create" + }); + win.center(); + win.open(); + win.addListener("close", () => { + if (win.getConfirmed()) { + this.__requestStartPipeline(studyId, partialPipeline, true); + } + }, this); + } else if (err.status == "402") { + osparc.FlashMessenger.logAs(msg, "WARNING"); + } else { + osparc.FlashMessenger.logAs(msg, "WARNING"); + this.getStudyLogger().error(null, "Unsuccessful pipeline submission"); + } + this.getStudy().setPipelineRunning(false); + }); + return true; }, From d1c77ba70c9b668f8de66f84265a7b9ca2ec3f20 Mon Sep 17 00:00:00 2001 From: odeimaiz Date: Tue, 13 May 2025 14:41:23 +0200 Subject: [PATCH 09/22] fetchJobsActive --- .../client/source/class/osparc/data/Resources.js | 5 ++--- .../client/source/class/osparc/desktop/MainPage.js | 2 +- .../client/source/class/osparc/jobs/JobsButton.js | 2 +- .../client/source/class/osparc/jobs/RunsTableModel.js | 4 ++-- .../client/source/class/osparc/store/Jobs.js | 11 +++++++++-- 5 files changed, 15 insertions(+), 9 deletions(-) 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 03547ba470f2..c6efb661c358 100644 --- a/services/static-webserver/client/source/class/osparc/data/Resources.js +++ b/services/static-webserver/client/source/class/osparc/data/Resources.js @@ -343,13 +343,12 @@ qx.Class.define("osparc.data.Resources", { }, } }, - "jobs": { + "jobsActive": { useCache: false, // handled in osparc.store.Jobs endpoints: { getPage: { method: "GET", - // url: statics.API + "/computations/-/iterations/latest?offset={offset}&limit={limit}&order_by={orderBy}" - url: statics.API + "/computations/-/iterations/latest?offset={offset}&limit={limit}&order_by=%7B%22field%22:%22submitted_at%22,%22direction%22:%22desc%22%7D" + url: statics.API + "/computations/-/iterations/latest?offset={offset}&limit={limit}&order_by=%7B%22field%22:%22submitted_at%22,%22direction%22:%22desc%22%7D&filter_only_running=true" }, } }, diff --git a/services/static-webserver/client/source/class/osparc/desktop/MainPage.js b/services/static-webserver/client/source/class/osparc/desktop/MainPage.js index 6d6095b2d4aa..2cf130e98716 100644 --- a/services/static-webserver/client/source/class/osparc/desktop/MainPage.js +++ b/services/static-webserver/client/source/class/osparc/desktop/MainPage.js @@ -69,7 +69,7 @@ qx.Class.define("osparc.desktop.MainPage", { preloadPromises.push(osparc.store.Tags.getInstance().fetchTags()); preloadPromises.push(osparc.store.Products.getInstance().fetchUiConfig()); preloadPromises.push(osparc.store.PollTasks.getInstance().fetchTasks()); - preloadPromises.push(osparc.store.Jobs.getInstance().fetchJobs()); + preloadPromises.push(osparc.store.Jobs.getInstance().fetchJobsActive()); Promise.all(preloadPromises) .then(() => { const mainStack = this.__createMainStack(); diff --git a/services/static-webserver/client/source/class/osparc/jobs/JobsButton.js b/services/static-webserver/client/source/class/osparc/jobs/JobsButton.js index c0df3017ee9c..3256962881bc 100644 --- a/services/static-webserver/client/source/class/osparc/jobs/JobsButton.js +++ b/services/static-webserver/client/source/class/osparc/jobs/JobsButton.js @@ -34,7 +34,7 @@ qx.Class.define("osparc.jobs.JobsButton", { this.addListener("tap", () => osparc.jobs.ActivityCenterWindow.openWindow(), this); const jobsStore = osparc.store.Jobs.getInstance(); - jobsStore.addListener("changeJobs", e => this.__updateJobsButton(), this); + jobsStore.addListener("changeJobs", () => this.__updateJobsButton(), this); }, members: { 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 1f80a5fcb4f7..da829b670989 100644 --- a/services/static-webserver/client/source/class/osparc/jobs/RunsTableModel.js +++ b/services/static-webserver/client/source/class/osparc/jobs/RunsTableModel.js @@ -60,7 +60,7 @@ qx.Class.define("osparc.jobs.RunsTableModel", { const offset = 0; const limit = 1; const resolveWResponse = true; - osparc.store.Jobs.getInstance().fetchJobs(offset, limit, JSON.stringify(this.getOrderBy()), resolveWResponse) + osparc.store.Jobs.getInstance().fetchJobsActive(offset, limit, JSON.stringify(this.getOrderBy()), resolveWResponse) .then(resp => { this._onRowCountLoaded(resp["_meta"].total) }) @@ -76,7 +76,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) => { - return osparc.store.Jobs.getInstance().fetchJobs(offset, limit, JSON.stringify(this.getOrderBy())) + return osparc.store.Jobs.getInstance().fetchJobsActive(offset, limit, JSON.stringify(this.getOrderBy())) .then(jobs => { const data = []; const jobsCols = osparc.jobs.RunsTable.COLS; diff --git a/services/static-webserver/client/source/class/osparc/store/Jobs.js b/services/static-webserver/client/source/class/osparc/store/Jobs.js index 183d25c621fb..60ffa4636de8 100644 --- a/services/static-webserver/client/source/class/osparc/store/Jobs.js +++ b/services/static-webserver/client/source/class/osparc/store/Jobs.js @@ -25,6 +25,13 @@ qx.Class.define("osparc.store.Jobs", { init: [], nullable: true, event: "changeJobs" + }, + + jobsActive: { + check: "Array", + init: [], + nullable: true, + event: "changeJobsActive" } }, @@ -33,7 +40,7 @@ qx.Class.define("osparc.store.Jobs", { }, members: { - fetchJobs: function( + fetchJobsActive: function( offset = 0, limit = this.self().SERVER_MAX_LIMIT, orderBy = { @@ -52,7 +59,7 @@ qx.Class.define("osparc.store.Jobs", { const options = { resolveWResponse: true }; - return osparc.data.Resources.fetch("jobs", "getPage", params, options) + return osparc.data.Resources.fetch("jobsActive", "getPage", params, options) .then(jobsResp => { const jobs = []; if ("data" in jobsResp) { From 1ee59e90bbe7b0f962a30cf60408b3fe64ad1522 Mon Sep 17 00:00:00 2001 From: odeimaiz Date: Tue, 13 May 2025 15:18:32 +0200 Subject: [PATCH 10/22] jobsActive --- .../source/class/osparc/jobs/JobsButton.js | 7 +++--- .../client/source/class/osparc/store/Jobs.js | 25 +++++++------------ 2 files changed, 12 insertions(+), 20 deletions(-) diff --git a/services/static-webserver/client/source/class/osparc/jobs/JobsButton.js b/services/static-webserver/client/source/class/osparc/jobs/JobsButton.js index 3256962881bc..2651747a5682 100644 --- a/services/static-webserver/client/source/class/osparc/jobs/JobsButton.js +++ b/services/static-webserver/client/source/class/osparc/jobs/JobsButton.js @@ -27,14 +27,14 @@ qx.Class.define("osparc.jobs.JobsButton", { width: 30, alignX: "center", cursor: "pointer", - visibility: "excluded", toolTipText: this.tr("Activity Center"), }); this.addListener("tap", () => osparc.jobs.ActivityCenterWindow.openWindow(), this); const jobsStore = osparc.store.Jobs.getInstance(); - jobsStore.addListener("changeJobs", () => this.__updateJobsButton(), this); + jobsStore.addListener("changeJobsActive", () => this.__updateJobsButton(), this); + this.__updateJobsButton(); }, members: { @@ -76,9 +76,8 @@ qx.Class.define("osparc.jobs.JobsButton", { const number = this.getChildControl("number"); const jobsStore = osparc.store.Jobs.getInstance(); - const nJobs = jobsStore.getJobs().length > 20 ? "20+" : jobsStore.getJobs().length; + const nJobs = jobsStore.getJobsActive().length > osparc.store.Jobs.SERVER_MAX_LIMIT ? (osparc.store.Jobs.SERVER_MAX_LIMIT + "+") : jobsStore.getJobsActive().length; number.setValue(nJobs.toString()); - nJobs ? this.show() : this.exclude(); }, } }); diff --git a/services/static-webserver/client/source/class/osparc/store/Jobs.js b/services/static-webserver/client/source/class/osparc/store/Jobs.js index 60ffa4636de8..fdfdc2004f9e 100644 --- a/services/static-webserver/client/source/class/osparc/store/Jobs.js +++ b/services/static-webserver/client/source/class/osparc/store/Jobs.js @@ -20,13 +20,6 @@ qx.Class.define("osparc.store.Jobs", { type: "singleton", properties: { - jobs: { - check: "Array", - init: [], - nullable: true, - event: "changeJobs" - }, - jobsActive: { check: "Array", init: [], @@ -61,16 +54,16 @@ qx.Class.define("osparc.store.Jobs", { }; return osparc.data.Resources.fetch("jobsActive", "getPage", params, options) .then(jobsResp => { - const jobs = []; + const jobsActive = []; if ("data" in jobsResp) { - jobsResp["data"].forEach(jobData => { - jobs.push(this.addJob(jobData)); + jobsResp["data"].forEach(jobActiveData => { + jobsActive.push(this.__addJobActive(jobActiveData)); }); } if (resolveWResponse) { return jobsResp; } - return jobs; + return jobsActive; }) .catch(err => console.error(err)); }, @@ -92,16 +85,16 @@ qx.Class.define("osparc.store.Jobs", { .catch(err => console.error(err)); }, - addJob: function(jobData) { - const jobs = this.getJobs(); - const jobFound = jobs.find(job => job.getProjectUuid() === jobData["projectUuid"]); + __addJobActive: function(jobData) { + const jobsActive = this.getJobsActive(); + const jobFound = jobsActive.find(job => job.getProjectUuid() === jobData["projectUuid"]); if (jobFound) { jobFound.updateJob(jobData); return jobFound; } const job = new osparc.data.Job(jobData); - jobs.push(job); - this.fireDataEvent("changeJobs"); + jobsActive.push(job); + this.fireDataEvent("changeJobsActive"); return job; }, From 28e8a63fb95dbb8ce2989b62f1190b4917777064 Mon Sep 17 00:00:00 2001 From: odeimaiz Date: Tue, 13 May 2025 15:47:07 +0200 Subject: [PATCH 11/22] changeJobsActive --- .../class/osparc/dashboard/ResourceDetails.js | 26 +++++++++++++ .../class/osparc/jobs/ActivityOverview.js | 39 +++++++++++++++++++ .../source/class/osparc/jobs/JobsButton.js | 9 ++--- .../client/source/class/osparc/store/Jobs.js | 22 ++++++----- 4 files changed, 82 insertions(+), 14 deletions(-) create mode 100644 services/static-webserver/client/source/class/osparc/jobs/ActivityOverview.js 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 d066ff1ab103..96c3c4cfb426 100644 --- a/services/static-webserver/client/source/class/osparc/dashboard/ResourceDetails.js +++ b/services/static-webserver/client/source/class/osparc/dashboard/ResourceDetails.js @@ -337,6 +337,7 @@ qx.Class.define("osparc.dashboard.ResourceDetails", { [ this.__getInfoPage, this.__getBillingPage, + this.__getActivityOverviewPage, this.__getServicesUpdatePage, this.__getServicesBootOptionsPage, this.__getConversationsPage, @@ -494,6 +495,31 @@ qx.Class.define("osparc.dashboard.ResourceDetails", { return null; }, + __getActivityOverviewPage: function() { + const resourceData = this.__resourceData; + if ( + !osparc.desktop.credits.Utils.areWalletsEnabled() || + !osparc.utils.Resources.isStudy(resourceData) + ) { + return null; + } + + const id = "ActivityOverview"; + const title = this.tr("Activity Overview"); + const iconSrc = "@FontAwesome5Solid/tasks/22"; + const page = this.__billingSettings = new osparc.dashboard.resources.pages.BasePage(title, iconSrc, id); + this.__addOpenButton(page); + + const lazyLoadContent = () => { + const activityOverview = new osparc.jobs.ActivityOverview(resourceData); + const billingScroll = new qx.ui.container.Scroll(activityOverview); + page.addToContent(billingScroll); + } + page.addListenerOnce("appear", lazyLoadContent, this); + + return page; + }, + __getPreviewPage: function() { const resourceData = this.__resourceData; if ( diff --git a/services/static-webserver/client/source/class/osparc/jobs/ActivityOverview.js b/services/static-webserver/client/source/class/osparc/jobs/ActivityOverview.js new file mode 100644 index 000000000000..e52a4e4bfc5e --- /dev/null +++ b/services/static-webserver/client/source/class/osparc/jobs/ActivityOverview.js @@ -0,0 +1,39 @@ +/* ************************************************************************ + + osparc - the simcore frontend + + https://osparc.io + + Copyright: + 2025 IT'IS Foundation, https://itis.swiss + + License: + MIT: https://opensource.org/licenses/MIT + + Authors: + * Odei Maiz (odeimaiz) + +************************************************************************ */ + +qx.Class.define("osparc.jobs.ActivityOverview", { + extend: qx.ui.core.Widget, + + construct: function(projectData) { + this.base(arguments); + + this._setLayout(new qx.ui.layout.VBox(15)); + + this.__buildLayout(projectData); + }, + + members: { + __buildLayout: function(projectData) { + const subRunsTable = new osparc.jobs.SubRunsTable(projectData["uuid"]); + this._add(subRunsTable); + + this.addListener("close", () => { + subRunsTable.stopInterval(); + }); + }, + } +}); diff --git a/services/static-webserver/client/source/class/osparc/jobs/JobsButton.js b/services/static-webserver/client/source/class/osparc/jobs/JobsButton.js index 2651747a5682..b5362ab59529 100644 --- a/services/static-webserver/client/source/class/osparc/jobs/JobsButton.js +++ b/services/static-webserver/client/source/class/osparc/jobs/JobsButton.js @@ -33,8 +33,8 @@ qx.Class.define("osparc.jobs.JobsButton", { this.addListener("tap", () => osparc.jobs.ActivityCenterWindow.openWindow(), this); const jobsStore = osparc.store.Jobs.getInstance(); - jobsStore.addListener("changeJobsActive", () => this.__updateJobsButton(), this); - this.__updateJobsButton(); + jobsStore.addListener("changeJobsActive", e => this.__updateJobsButton(e.getData()), this); + jobsStore.fetchJobsActive(); }, members: { @@ -71,12 +71,11 @@ qx.Class.define("osparc.jobs.JobsButton", { return control || this.base(arguments, id); }, - __updateJobsButton: function() { + __updateJobsButton: function(nActiveJobs) { this.getChildControl("icon"); const number = this.getChildControl("number"); - const jobsStore = osparc.store.Jobs.getInstance(); - const nJobs = jobsStore.getJobsActive().length > osparc.store.Jobs.SERVER_MAX_LIMIT ? (osparc.store.Jobs.SERVER_MAX_LIMIT + "+") : jobsStore.getJobsActive().length; + const nJobs = nActiveJobs > osparc.store.Jobs.SERVER_MAX_LIMIT ? (osparc.store.Jobs.SERVER_MAX_LIMIT + "+") : nActiveJobs; number.setValue(nJobs.toString()); }, } diff --git a/services/static-webserver/client/source/class/osparc/store/Jobs.js b/services/static-webserver/client/source/class/osparc/store/Jobs.js index fdfdc2004f9e..030da0c3f519 100644 --- a/services/static-webserver/client/source/class/osparc/store/Jobs.js +++ b/services/static-webserver/client/source/class/osparc/store/Jobs.js @@ -20,12 +20,16 @@ qx.Class.define("osparc.store.Jobs", { type: "singleton", properties: { - jobsActive: { + jobs: { check: "Array", init: [], nullable: true, - event: "changeJobsActive" - } + event: "changeJobs" + }, + }, + + events: { + "changeJobsActive": "qx.event.type.Data", }, statics: { @@ -54,10 +58,11 @@ qx.Class.define("osparc.store.Jobs", { }; return osparc.data.Resources.fetch("jobsActive", "getPage", params, options) .then(jobsResp => { + this.fireDataEvent("changeJobsActive", jobsResp["_meta"]["total"]); const jobsActive = []; if ("data" in jobsResp) { jobsResp["data"].forEach(jobActiveData => { - jobsActive.push(this.__addJobActive(jobActiveData)); + jobsActive.push(this.__addJob(jobActiveData)); }); } if (resolveWResponse) { @@ -85,16 +90,15 @@ qx.Class.define("osparc.store.Jobs", { .catch(err => console.error(err)); }, - __addJobActive: function(jobData) { - const jobsActive = this.getJobsActive(); - const jobFound = jobsActive.find(job => job.getProjectUuid() === jobData["projectUuid"]); + __addJob: function(jobData) { + const jobs = this.getJobs(); + const jobFound = jobs.find(job => job.getProjectUuid() === jobData["projectUuid"]); if (jobFound) { jobFound.updateJob(jobData); return jobFound; } const job = new osparc.data.Job(jobData); - jobsActive.push(job); - this.fireDataEvent("changeJobsActive"); + jobs.push(job); return job; }, From 03feac0a1cbacfa55b24edb1f74ca3bfd8d0984d Mon Sep 17 00:00:00 2001 From: odeimaiz Date: Tue, 13 May 2025 15:58:08 +0200 Subject: [PATCH 12/22] addSubJob --- .../client/source/class/osparc/data/Job.js | 5 +++-- .../client/source/class/osparc/store/Jobs.js | 15 +++++++++------ 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/services/static-webserver/client/source/class/osparc/data/Job.js b/services/static-webserver/client/source/class/osparc/data/Job.js index 31d8456a0b0a..84aa0e2bd2a6 100644 --- a/services/static-webserver/client/source/class/osparc/data/Job.js +++ b/services/static-webserver/client/source/class/osparc/data/Job.js @@ -23,7 +23,7 @@ qx.Class.define("osparc.data.Job", { this.set({ projectUuid: jobData["projectUuid"], - state: jobData["state"], + state: jobData["state"] || "UNKNOWN", submittedAt: jobData["submittedAt"] ? new Date(jobData["submittedAt"]) : null, startedAt: jobData["startedAt"] ? new Date(jobData["startedAt"]) : null, endedAt: jobData["endedAt"] ? new Date(jobData["endedAt"]) : null, @@ -76,13 +76,14 @@ qx.Class.define("osparc.data.Job", { info: { check: "Object", - nullable: false, + nullable: true, init: null, }, }, statics: { STATUS_LABELS: { + "UNKNOWN": "Unknown", "NOT_STARTED": "Not Started", "PUBLISHED": "Published", "PENDING": "Pending", diff --git a/services/static-webserver/client/source/class/osparc/store/Jobs.js b/services/static-webserver/client/source/class/osparc/store/Jobs.js index 030da0c3f519..74e40653024d 100644 --- a/services/static-webserver/client/source/class/osparc/store/Jobs.js +++ b/services/static-webserver/client/source/class/osparc/store/Jobs.js @@ -103,13 +103,16 @@ qx.Class.define("osparc.store.Jobs", { }, addSubJob: function(subJobData) { - const jobs = this.getJobs(); - const jobFound = jobs.find(job => job.getProjectUuid() === subJobData["projectUuid"]); - if (jobFound) { - const subJob = jobFound.addSubJob(subJobData); - return subJob; + let job = this.getJob(subJobData["projectUuid"]); + if (!job) { + const jobs = this.getJobs(); + const unknownJob = new osparc.data.Job({ + "projectUuid": subJobData["projectUuid"], + }); + jobs.push(unknownJob); } - return null; + const subJob = job.addSubJob(subJobData); + return subJob; }, getJob: function(projectUuid) { From 9b1dfb47663f80187a76058c9cdedbcec6a774bc Mon Sep 17 00:00:00 2001 From: odeimaiz Date: Tue, 13 May 2025 16:00:00 +0200 Subject: [PATCH 13/22] fix --- .../static-webserver/client/source/class/osparc/store/Jobs.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/services/static-webserver/client/source/class/osparc/store/Jobs.js b/services/static-webserver/client/source/class/osparc/store/Jobs.js index 74e40653024d..87ea782e18a6 100644 --- a/services/static-webserver/client/source/class/osparc/store/Jobs.js +++ b/services/static-webserver/client/source/class/osparc/store/Jobs.js @@ -106,10 +106,10 @@ qx.Class.define("osparc.store.Jobs", { let job = this.getJob(subJobData["projectUuid"]); if (!job) { const jobs = this.getJobs(); - const unknownJob = new osparc.data.Job({ + job = new osparc.data.Job({ "projectUuid": subJobData["projectUuid"], }); - jobs.push(unknownJob); + jobs.push(job); } const subJob = job.addSubJob(subJobData); return subJob; From eb675e996625cdd01213ac289bc6ef79a3b15bf9 Mon Sep 17 00:00:00 2001 From: odeimaiz Date: Tue, 13 May 2025 16:05:38 +0200 Subject: [PATCH 14/22] minor --- .../client/source/class/osparc/jobs/ActivityOverview.js | 4 ---- 1 file changed, 4 deletions(-) diff --git a/services/static-webserver/client/source/class/osparc/jobs/ActivityOverview.js b/services/static-webserver/client/source/class/osparc/jobs/ActivityOverview.js index e52a4e4bfc5e..34908d41218d 100644 --- a/services/static-webserver/client/source/class/osparc/jobs/ActivityOverview.js +++ b/services/static-webserver/client/source/class/osparc/jobs/ActivityOverview.js @@ -30,10 +30,6 @@ qx.Class.define("osparc.jobs.ActivityOverview", { __buildLayout: function(projectData) { const subRunsTable = new osparc.jobs.SubRunsTable(projectData["uuid"]); this._add(subRunsTable); - - this.addListener("close", () => { - subRunsTable.stopInterval(); - }); }, } }); From 415d5eeaa06fc8f872ebacd4cbb23835c92a9f89 Mon Sep 17 00:00:00 2001 From: odeimaiz Date: Tue, 13 May 2025 16:13:22 +0200 Subject: [PATCH 15/22] customMetadata prop --- .../client/source/class/osparc/data/Job.js | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/services/static-webserver/client/source/class/osparc/data/Job.js b/services/static-webserver/client/source/class/osparc/data/Job.js index 84aa0e2bd2a6..34b7d1ec190c 100644 --- a/services/static-webserver/client/source/class/osparc/data/Job.js +++ b/services/static-webserver/client/source/class/osparc/data/Job.js @@ -28,6 +28,7 @@ qx.Class.define("osparc.data.Job", { startedAt: jobData["startedAt"] ? new Date(jobData["startedAt"]) : null, endedAt: jobData["endedAt"] ? new Date(jobData["endedAt"]) : null, info: jobData["info"] || null, + customMetadata: jobData["customMetadata"] || null, }); if (jobData["info"] && jobData["info"]["project_name"]) { @@ -79,6 +80,12 @@ qx.Class.define("osparc.data.Job", { nullable: true, init: null, }, + + customMetadata: { + check: "Object", + nullable: true, + init: null, + }, }, statics: { From 2f1fd5f6af4028585ab3489a6d1e910f86d0b8ec Mon Sep 17 00:00:00 2001 From: odeimaiz Date: Tue, 13 May 2025 16:20:51 +0200 Subject: [PATCH 16/22] getLogDownloadLink --- .../source/class/osparc/jobs/SubRunsTable.js | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/services/static-webserver/client/source/class/osparc/jobs/SubRunsTable.js b/services/static-webserver/client/source/class/osparc/jobs/SubRunsTable.js index 1c4b2e7f95cf..ecdb587ac827 100644 --- a/services/static-webserver/client/source/class/osparc/jobs/SubRunsTable.js +++ b/services/static-webserver/client/source/class/osparc/jobs/SubRunsTable.js @@ -145,6 +145,7 @@ qx.Class.define("osparc.jobs.SubRunsTable", { }, __handleButtonClick: function(action, row) { + this.resetSelection(); const rowData = this.getTableModel().getRowData(row); switch (action) { case "info": { @@ -161,6 +162,23 @@ qx.Class.define("osparc.jobs.SubRunsTable", { win.setCaption(rowData["nodeName"]); break; } + case "logs": { + const job = osparc.store.Jobs.getInstance().getJob(rowData["projectUuid"]); + if (!job) { + return; + } + const subJob = job.getSubJob(rowData["nodeId"]); + if (!subJob) { + return; + } + const logDownloadLink = subJob.getLogDownloadLink() + if (logDownloadLink) { + osparc.utils.Utils.downloadLink(logDownloadLink, "GET", rowData["nodeName"] + ".logs"); + } else { + osparc.component.message.FlashMessenger.getInstance().logAsWarning(this.tr("No logs available")); + } + break; + } default: console.warn(`Unknown action: ${action}`); break; From d71305fcadf677b64c197bd9572bc0750e76c014 Mon Sep 17 00:00:00 2001 From: odeimaiz Date: Tue, 13 May 2025 16:24:46 +0200 Subject: [PATCH 17/22] stopPipeline --- .../source/class/osparc/data/Resources.js | 4 ++++ .../source/class/osparc/desktop/StudyEditor.js | 17 +++++++++-------- 2 files changed, 13 insertions(+), 8 deletions(-) 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 c6efb661c358..dcffb8738285 100644 --- a/services/static-webserver/client/source/class/osparc/data/Resources.js +++ b/services/static-webserver/client/source/class/osparc/data/Resources.js @@ -341,6 +341,10 @@ qx.Class.define("osparc.data.Resources", { method: "POST", url: statics.API + "/computations/{studyId}:start" }, + stopPipeline: { + method: "POST", + url: statics.API + "/computations/{studyId}:stop" + }, } }, "jobsActive": { 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 0a909d80d3f1..a697a6f0e9f1 100644 --- a/services/static-webserver/client/source/class/osparc/desktop/StudyEditor.js +++ b/services/static-webserver/client/source/class/osparc/desktop/StudyEditor.js @@ -666,15 +666,16 @@ qx.Class.define("osparc.desktop.StudyEditor", { }, __requestStopPipeline: function(studyId) { - const url = "/computations/" + encodeURIComponent(studyId) + ":stop"; - const req = new osparc.io.request.ApiRequest(url, "POST"); - req.addListener("success", () => this.getStudyLogger().debug(null, "Pipeline aborting"), this); - req.addListener("error", () => this.getStudyLogger().error(null, "Error stopping pipeline"), this); - req.addListener("fail", () => this.getStudyLogger().error(null, "Failed stopping pipeline"), this); - req.send(); - this.getStudyLogger().info(null, "Stopping pipeline"); - return true; + + const params = { + url: { + "studyId": studyId + }, + }; + osparc.data.Resources.fetch("runPipeline", "stopPipeline", params) + .then(() => this.getStudyLogger().debug(null, "Pipeline aborting"), this) + .catch(() => this.getStudyLogger().error(null, "Error stopping pipeline"), this); }, // ------------------ START/STOP PIPELINE ------------------ From 4021a69b10602d005f9b3bc3747245bff03c5dde Mon Sep 17 00:00:00 2001 From: odeimaiz Date: Tue, 13 May 2025 16:28:51 +0200 Subject: [PATCH 18/22] minor --- .../client/source/class/osparc/desktop/StudyEditor.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 a697a6f0e9f1..0575c2bd11d0 100644 --- a/services/static-webserver/client/source/class/osparc/desktop/StudyEditor.js +++ b/services/static-webserver/client/source/class/osparc/desktop/StudyEditor.js @@ -674,7 +674,7 @@ qx.Class.define("osparc.desktop.StudyEditor", { }, }; osparc.data.Resources.fetch("runPipeline", "stopPipeline", params) - .then(() => this.getStudyLogger().debug(null, "Pipeline aborting"), this) + .then(() => this.getStudyLogger().debug(null, "Stopping pipeline"), this) .catch(() => this.getStudyLogger().error(null, "Error stopping pipeline"), this); }, // ------------------ START/STOP PIPELINE ------------------ From f79492fe89069d27be36abfc777e4aaec591de5c Mon Sep 17 00:00:00 2001 From: odeimaiz Date: Tue, 13 May 2025 16:39:09 +0200 Subject: [PATCH 19/22] Stopping pipeline --- .../source/class/osparc/jobs/RunsTable.js | 30 +++++++++++++++---- 1 file changed, 24 insertions(+), 6 deletions(-) diff --git a/services/static-webserver/client/source/class/osparc/jobs/RunsTable.js b/services/static-webserver/client/source/class/osparc/jobs/RunsTable.js index 3108bb26a612..f22b523592df 100644 --- a/services/static-webserver/client/source/class/osparc/jobs/RunsTable.js +++ b/services/static-webserver/client/source/class/osparc/jobs/RunsTable.js @@ -132,17 +132,35 @@ qx.Class.define("osparc.jobs.RunsTable", { }, __handleButtonClick: function(action, row) { + this.resetSelection(); const rowData = this.getTableModel().getRowData(row); switch (action) { case "info": { - this.fireDataEvent("runSelected", rowData); + const job = osparc.store.Jobs.getInstance().getJob(rowData["projectUuid"]); + if (!job) { + return; + } + const allInfo = { + "image": job.getInfo() ? osparc.utils.Utils.deepCloneObject(job.getInfo()) : {}, + "customMetadata": job.getCustomMetadata() ? osparc.utils.Utils.deepCloneObject(job.getCustomMetadata()) : {}, + } + const runInfo = new osparc.jobs.Info(allInfo); + const win = osparc.jobs.Info.popUpInWindow(runInfo); + win.setCaption(rowData["projectName"]); break; } - case "run": - case "stop": - case "logs": { - const msg = `I wish I could ${action} the job ${rowData["projectUuid"]}`; - osparc.FlashMessenger.logAs(msg, "WARNING"); + case "cancel": { + const params = { + url: { + "studyId": rowData["projectUuid"], + }, + }; + osparc.data.Resources.fetch("runPipeline", "stopPipeline", params) + .then(() => { + const msg = qx.locale.Manager.tr("Stopping pipeline {0}", rowData["projectName"]); + osparc.FlashMessenger.logAs(msg, "INFO"); + }) + .catch(err => osparc.FlashMessenger.logError(err)); break; } default: From 46948ac785496c61e56e33d16cc427a83dc17ddc Mon Sep 17 00:00:00 2001 From: odeimaiz Date: Tue, 13 May 2025 16:41:07 +0200 Subject: [PATCH 20/22] minor --- .../client/source/class/osparc/jobs/RunsTable.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/static-webserver/client/source/class/osparc/jobs/RunsTable.js b/services/static-webserver/client/source/class/osparc/jobs/RunsTable.js index f22b523592df..9d16c3225377 100644 --- a/services/static-webserver/client/source/class/osparc/jobs/RunsTable.js +++ b/services/static-webserver/client/source/class/osparc/jobs/RunsTable.js @@ -157,7 +157,7 @@ qx.Class.define("osparc.jobs.RunsTable", { }; osparc.data.Resources.fetch("runPipeline", "stopPipeline", params) .then(() => { - const msg = qx.locale.Manager.tr("Stopping pipeline {0}", rowData["projectName"]); + const msg = this.tr("Stopping pipeline"); osparc.FlashMessenger.logAs(msg, "INFO"); }) .catch(err => osparc.FlashMessenger.logError(err)); From a226bc770adbeac4d9fa2e722d3ab253ebba4823 Mon Sep 17 00:00:00 2001 From: odeimaiz Date: Tue, 13 May 2025 17:02:11 +0200 Subject: [PATCH 21/22] open it in a nwe window --- .../class/osparc/dashboard/ResourceDetails.js | 96 ++++++++++--------- .../class/osparc/jobs/ActivityCenterWindow.js | 7 +- .../class/osparc/jobs/ActivityOverview.js | 8 ++ 3 files changed, 62 insertions(+), 49 deletions(-) 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 96c3c4cfb426..6677e485689a 100644 --- a/services/static-webserver/client/source/class/osparc/dashboard/ResourceDetails.js +++ b/services/static-webserver/client/source/class/osparc/dashboard/ResourceDetails.js @@ -337,7 +337,6 @@ qx.Class.define("osparc.dashboard.ResourceDetails", { [ this.__getInfoPage, this.__getBillingPage, - this.__getActivityOverviewPage, this.__getServicesUpdatePage, this.__getServicesBootOptionsPage, this.__getConversationsPage, @@ -357,27 +356,9 @@ qx.Class.define("osparc.dashboard.ResourceDetails", { } }); - const resourceData = this.__resourceData; - if (!osparc.utils.Resources.isService(resourceData)) { - const title = osparc.product.Utils.getStudyAlias({firstUpperCase: true}) + this.tr(" Files..."); - const iconSrc = "@FontAwesome5Solid/file/22"; - const dataAccess = new qx.ui.basic.Atom().set({ - label: title, - icon: iconSrc, - font: "text-14", - padding: 8, - paddingLeft: 12, - gap: 14, - cursor: "pointer", - }); - dataAccess.addListener("tap", () => osparc.widget.StudyDataManager.popUpInWindow(resourceData["uuid"])); - this.addWidgetToTabs(dataAccess); - if (resourceData["resourceType"] === "study") { - const canShowData = osparc.study.Utils.canShowStudyData(resourceData); - dataAccess.setEnabled(canShowData); - } - } + this.__getActivityOverviewPopUp(); + this.__getProjectFilesPopUp(); if (selectedTabId) { const pageFound = tabsView.getChildren().find(page => page.tabId === selectedTabId); @@ -495,31 +476,6 @@ qx.Class.define("osparc.dashboard.ResourceDetails", { return null; }, - __getActivityOverviewPage: function() { - const resourceData = this.__resourceData; - if ( - !osparc.desktop.credits.Utils.areWalletsEnabled() || - !osparc.utils.Resources.isStudy(resourceData) - ) { - return null; - } - - const id = "ActivityOverview"; - const title = this.tr("Activity Overview"); - const iconSrc = "@FontAwesome5Solid/tasks/22"; - const page = this.__billingSettings = new osparc.dashboard.resources.pages.BasePage(title, iconSrc, id); - this.__addOpenButton(page); - - const lazyLoadContent = () => { - const activityOverview = new osparc.jobs.ActivityOverview(resourceData); - const billingScroll = new qx.ui.container.Scroll(activityOverview); - page.addToContent(billingScroll); - } - page.addListenerOnce("appear", lazyLoadContent, this); - - return page; - }, - __getPreviewPage: function() { const resourceData = this.__resourceData; if ( @@ -840,6 +796,52 @@ qx.Class.define("osparc.dashboard.ResourceDetails", { page.addToHeader(toolbar); page.addToContent(createFunction); return page; - } + }, + + __getProjectFilesPopUp: function() { + const resourceData = this.__resourceData; + if (!osparc.utils.Resources.isService(resourceData)) { + const title = osparc.product.Utils.getStudyAlias({firstUpperCase: true}) + this.tr(" Files..."); + const iconSrc = "@FontAwesome5Solid/file/22"; + const dataAccess = new qx.ui.basic.Atom().set({ + label: title, + icon: iconSrc, + font: "text-14", + padding: 8, + paddingLeft: 12, + gap: 14, + cursor: "pointer", + }); + dataAccess.addListener("tap", () => osparc.widget.StudyDataManager.popUpInWindow(resourceData["uuid"])); + this.addWidgetToTabs(dataAccess); + + if (resourceData["resourceType"] === "study") { + const canShowData = osparc.study.Utils.canShowStudyData(resourceData); + dataAccess.setEnabled(canShowData); + } + } + }, + + __getActivityOverviewPopUp: function() { + const resourceData = this.__resourceData; + if ( + osparc.desktop.credits.Utils.areWalletsEnabled() && + osparc.utils.Resources.isStudy(resourceData) + ) { + const title = this.tr("Activity Overview..."); + const iconSrc = "@FontAwesome5Solid/tasks/22"; + const dataAccess = new qx.ui.basic.Atom().set({ + label: title, + icon: iconSrc, + font: "text-14", + padding: 8, + paddingLeft: 10, + gap: 12, // align with the rest of the tabs + cursor: "pointer", + }); + dataAccess.addListener("tap", () => osparc.jobs.ActivityOverview.popUpInWindow(resourceData)); + this.addWidgetToTabs(dataAccess); + } + }, } }); 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 cd56d3198f6d..7f2fe3b7b023 100644 --- a/services/static-webserver/client/source/class/osparc/jobs/ActivityCenterWindow.js +++ b/services/static-webserver/client/source/class/osparc/jobs/ActivityCenterWindow.js @@ -24,8 +24,8 @@ qx.Class.define("osparc.jobs.ActivityCenterWindow", { this.set({ layout: new qx.ui.layout.VBox(), modal: true, - width: 1100, - height: 500, + width: this.self().WIDTH, + height: this.self().HEIGHT, showMaximize: false, showMinimize: false, }); @@ -34,6 +34,9 @@ qx.Class.define("osparc.jobs.ActivityCenterWindow", { }, statics: { + WIDTH: 1000, + HEIGHT: 500, + openWindow: function() { const runsWindow = new osparc.jobs.ActivityCenterWindow(); runsWindow.center(); diff --git a/services/static-webserver/client/source/class/osparc/jobs/ActivityOverview.js b/services/static-webserver/client/source/class/osparc/jobs/ActivityOverview.js index 34908d41218d..0f985f4e03da 100644 --- a/services/static-webserver/client/source/class/osparc/jobs/ActivityOverview.js +++ b/services/static-webserver/client/source/class/osparc/jobs/ActivityOverview.js @@ -26,6 +26,14 @@ qx.Class.define("osparc.jobs.ActivityOverview", { this.__buildLayout(projectData); }, + statics: { + popUpInWindow: function(projectData) { + const activityOverview = new osparc.jobs.ActivityOverview(projectData); + const title = qx.locale.Manager.tr("Activity Overview"); + return osparc.ui.window.Window.popUpInWindow(activityOverview, title, osparc.jobs.ActivityCenterWindow.WIDTH, osparc.jobs.ActivityCenterWindow.HEIGHT); + }, + }, + members: { __buildLayout: function(projectData) { const subRunsTable = new osparc.jobs.SubRunsTable(projectData["uuid"]); From f2e7234c6e81bcfb7b8dc44a2e4010e0d3846c47 Mon Sep 17 00:00:00 2001 From: odeimaiz Date: Tue, 13 May 2025 17:04:48 +0200 Subject: [PATCH 22/22] copiloting --- .../client/source/class/osparc/desktop/StudyEditor.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) 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 0575c2bd11d0..9110b9ca8140 100644 --- a/services/static-webserver/client/source/class/osparc/desktop/StudyEditor.js +++ b/services/static-webserver/client/source/class/osparc/desktop/StudyEditor.js @@ -597,7 +597,7 @@ qx.Class.define("osparc.desktop.StudyEditor", { } }; osparc.data.Resources.fetch("runPipeline", "startPipeline", params) - .then(() => this.__onPipelineSubmitted) + .then(() => this.__onPipelineSubmitted()) .catch(err => { let msg = err.message; const errStatus = err.status; @@ -662,15 +662,15 @@ qx.Class.define("osparc.desktop.StudyEditor", { return; } - this.__requestStopPipeline(this.getStudy().getUuid()); + this.__requestStopPipeline(); }, - __requestStopPipeline: function(studyId) { + __requestStopPipeline: function() { this.getStudyLogger().info(null, "Stopping pipeline"); const params = { url: { - "studyId": studyId + "studyId": this.getStudy().getUuid() }, }; osparc.data.Resources.fetch("runPipeline", "stopPipeline", params)