From d1c015459d2bcde8927480765412fd687d1a1951 Mon Sep 17 00:00:00 2001 From: John Chilton Date: Fri, 6 Dec 2024 11:57:49 -0500 Subject: [PATCH] Metrics usability - link dots to jobs. --- client/src/api/schema/schema.ts | 2 ++ .../WorkflowInvocationMetrics.vue | 9 +++++++++ lib/galaxy/managers/jobs.py | 4 ++-- lib/galaxy/schema/schema.py | 1 + lib/galaxy/webapps/galaxy/services/invocations.py | 13 ++++++++----- 5 files changed, 22 insertions(+), 7 deletions(-) diff --git a/client/src/api/schema/schema.ts b/client/src/api/schema/schema.ts index abc681fb8ca3..c1ab9156064e 100644 --- a/client/src/api/schema/schema.ts +++ b/client/src/api/schema/schema.ts @@ -18470,6 +18470,8 @@ export interface components { * } */ WorkflowJobMetric: { + /** Job Id */ + job_id: string; /** * Name * @description The name of the metric variable. diff --git a/client/src/components/WorkflowInvocationState/WorkflowInvocationMetrics.vue b/client/src/components/WorkflowInvocationState/WorkflowInvocationMetrics.vue index 91782651b709..9b836aa3757f 100644 --- a/client/src/components/WorkflowInvocationState/WorkflowInvocationMetrics.vue +++ b/client/src/components/WorkflowInvocationState/WorkflowInvocationMetrics.vue @@ -4,6 +4,7 @@ import { computed, ref, watch } from "vue"; import { type ComputedRef } from "vue"; import { type components, GalaxyApi } from "@/api"; +import { getAppRoot } from "@/onload/loadConfig"; import { errorMessageAsString } from "@/utils/simple-error"; const VegaWrapper = () => import("./VegaWrapper.vue"); @@ -72,6 +73,8 @@ function metricToSpecData( return { y, x: itemToX(item), + job_id: item.job_id, + tooltip: "click to view job", }; }); return { @@ -109,6 +112,10 @@ function itemToSpec(item: boxplotData) { calculate: "random() - 0.5", as: "random_jitter", }, + { + calculate: "'" + getAppRoot() + "jobs/' + datum.job_id + '/view'", + as: "url", + }, ], layer: [ { @@ -141,6 +148,8 @@ function itemToSpec(item: boxplotData) { scale: { zero: false }, title: item.y_title, }, + tooltip: { field: "tooltip", type: "nominal" }, + href: { field: "url", type: "nominal" }, }, width: "container", }, diff --git a/lib/galaxy/managers/jobs.py b/lib/galaxy/managers/jobs.py index 1ef47ff34f46..48c04b3e656f 100644 --- a/lib/galaxy/managers/jobs.py +++ b/lib/galaxy/managers/jobs.py @@ -788,7 +788,7 @@ def invocation_job_source_iter(sa_session, invocation_id): def get_job_metrics_for_invocation(sa_session: galaxy_scoped_session, invocation_id: int): single_job_stmnt = ( - select(WorkflowStep.order_index, Job.tool_id, WorkflowStep.label, JobMetricNumeric) + select(WorkflowStep.order_index, Job.id, Job.tool_id, WorkflowStep.label, JobMetricNumeric) .join(Job, JobMetricNumeric.job_id == Job.id) .join( WorkflowInvocationStep, @@ -799,7 +799,7 @@ def get_job_metrics_for_invocation(sa_session: galaxy_scoped_session, invocation .join(WorkflowStep, WorkflowStep.id == WorkflowInvocationStep.workflow_step_id) ) collection_job_stmnt = ( - select(WorkflowStep.order_index, Job.tool_id, WorkflowStep.label, JobMetricNumeric) + select(WorkflowStep.order_index, Job.id, Job.tool_id, WorkflowStep.label, JobMetricNumeric) .join(Job, JobMetricNumeric.job_id == Job.id) .join(ImplicitCollectionJobsJobAssociation, Job.id == ImplicitCollectionJobsJobAssociation.job_id) .join( diff --git a/lib/galaxy/schema/schema.py b/lib/galaxy/schema/schema.py index d1e05c577cec..841a81555f7b 100644 --- a/lib/galaxy/schema/schema.py +++ b/lib/galaxy/schema/schema.py @@ -2173,6 +2173,7 @@ class JobMetric(Model): class WorkflowJobMetric(JobMetric): tool_id: str + job_id: str step_index: int step_label: Optional[str] diff --git a/lib/galaxy/webapps/galaxy/services/invocations.py b/lib/galaxy/webapps/galaxy/services/invocations.py index 4db9a0d5f1a0..9b7ef61cc1ce 100644 --- a/lib/galaxy/webapps/galaxy/services/invocations.py +++ b/lib/galaxy/webapps/galaxy/services/invocations.py @@ -167,19 +167,22 @@ def show_invocation_step(self, trans, step_id) -> InvocationStep: def show_invocation_metrics(self, trans: ProvidesHistoryContext, invocation_id: int): extended_job_metrics = get_job_metrics_for_invocation(trans.sa_session, invocation_id) job_metrics = [] + job_ids = [] tool_ids = [] step_indexes = [] step_labels = [] for row in extended_job_metrics: step_indexes.append(row[0]) - tool_ids.append(row[1]) - step_labels.append(row[2]) - job_metrics.append(row[3]) + job_ids.append(row[1]) + tool_ids.append(row[2]) + step_labels.append(row[3]) + job_metrics.append(row[4]) metrics_dict_list = summarize_metrics(trans, job_metrics) - for tool_id, step_index, step_label, metrics_dict in zip( - tool_ids, step_indexes, step_labels, metrics_dict_list + for tool_id, job_id, step_index, step_label, metrics_dict in zip( + tool_ids, job_ids, step_indexes, step_labels, metrics_dict_list ): metrics_dict["tool_id"] = tool_id + metrics_dict["job_id"] = trans.security.encode_id(job_id) metrics_dict["step_index"] = step_index metrics_dict["step_label"] = step_label return metrics_dict_list