@@ -61,7 +66,7 @@
- {{ labelForWorkflowStep(stepInput.source_step) }}
+
@@ -91,13 +96,15 @@ import { FontAwesomeIcon } from "@fortawesome/vue-fontawesome";
import GenericHistoryItem from "components/History/Content/GenericItem";
import LoadingSpan from "components/LoadingSpan";
import { InvocationStepProvider } from "components/providers";
-import WorkflowIcons from "components/Workflow/icons";
+import ToolLinkPopover from "components/Tool/ToolLinkPopover";
import { mapActions, mapState } from "pinia";
import { useToolStore } from "stores/toolStore";
import { useWorkflowStore } from "stores/workflowStore";
import JobStep from "./JobStep";
import ParameterStep from "./ParameterStep";
+import WorkflowStepIcon from "./WorkflowStepIcon";
+import WorkflowStepTitle from "./WorkflowStepTitle";
library.add(faChevronUp, faChevronDown);
@@ -109,6 +116,9 @@ export default {
ParameterStep,
InvocationStepProvider,
GenericHistoryItem,
+ ToolLinkPopover,
+ WorkflowStepIcon,
+ WorkflowStepTitle,
WorkflowInvocationState: () => import("components/WorkflowInvocationState/WorkflowInvocationState"),
},
props: {
@@ -140,16 +150,6 @@ export default {
isDataStep() {
return ["data_input", "data_collection_input"].includes(this.workflowStepType);
},
- stepIcon() {
- return WorkflowIcons[this.workflowStepType];
- },
- stepLabel() {
- return this.labelForWorkflowStep(this.workflowStep.id);
- },
- },
- created() {
- this.fetchTool();
- this.fetchSubworkflow();
},
methods: {
...mapActions(useWorkflowStore, ["fetchWorkflowForInstanceId"]),
@@ -167,31 +167,24 @@ export default {
toggleStep() {
this.expanded = !this.expanded;
},
- labelForWorkflowStep(stepIndex) {
+ toolProps(stepIndex) {
+ const workflowStep = this.workflow.steps[stepIndex];
+ return {
+ toolId: workflowStep.tool_id,
+ toolVersion: workflowStep.tool_version,
+ };
+ },
+ titleProps(stepIndex) {
const invocationStep = this.invocation.steps[stepIndex];
const workflowStep = this.workflow.steps[stepIndex];
- const oneBasedStepIndex = stepIndex + 1;
- if (invocationStep && invocationStep.workflow_step_label) {
- return `Step ${oneBasedStepIndex}: ${invocationStep.workflow_step_label}`;
- }
- const workflowStepType = workflowStep.type;
- switch (workflowStepType) {
- case "tool":
- return `Step ${oneBasedStepIndex}: ${this.getToolNameById(workflowStep.tool_id)}`;
- case "subworkflow": {
- const subworkflow = this.getStoredWorkflowByInstanceId(workflowStep.workflow_id);
- const label = subworkflow ? subworkflow.name : "Subworkflow";
- return `Step ${oneBasedStepIndex}: ${label}`;
- }
- case "parameter_input":
- return `Step ${oneBasedStepIndex}: Parameter input`;
- case "data_input":
- return `Step ${oneBasedStepIndex}: Data input`;
- case "data_collection_input":
- return `Step ${oneBasedStepIndex}: Data collection input`;
- default:
- return `Step ${oneBasedStepIndex}: Unknown step type '${workflowStepType}'`;
- }
+ const rval = {
+ stepIndex: stepIndex,
+ stepLabel: invocationStep && invocationStep.workflow_step_label,
+ stepType: workflowStep.type,
+ stepToolId: workflowStep.tool_id,
+ stepSubworkflowId: workflowStep.workflow_id,
+ };
+ return rval;
},
},
};
diff --git a/client/src/components/WorkflowInvocationState/WorkflowStepIcon.vue b/client/src/components/WorkflowInvocationState/WorkflowStepIcon.vue
new file mode 100644
index 000000000000..7b103f3d27cd
--- /dev/null
+++ b/client/src/components/WorkflowInvocationState/WorkflowStepIcon.vue
@@ -0,0 +1,20 @@
+
+
+
+
+
diff --git a/client/src/components/WorkflowInvocationState/WorkflowStepTitle.vue b/client/src/components/WorkflowInvocationState/WorkflowStepTitle.vue
new file mode 100644
index 000000000000..1253d73e3e40
--- /dev/null
+++ b/client/src/components/WorkflowInvocationState/WorkflowStepTitle.vue
@@ -0,0 +1,79 @@
+
+
+
+ {{ title }}
+
diff --git a/client/src/stores/jobStore.ts b/client/src/stores/jobStore.ts
index 8cb0dc3317b7..0de68bde3507 100644
--- a/client/src/stores/jobStore.ts
+++ b/client/src/stores/jobStore.ts
@@ -12,6 +12,8 @@ import { getAppRoot } from "@/onload/loadConfig";
/* interfaces */
interface Job {
id: string;
+ tool_id: string;
+ tool_version: string;
}
interface JobDef {
tool_id: string;
diff --git a/lib/galaxy/managers/markdown_parse.py b/lib/galaxy/managers/markdown_parse.py
index ae70de230f91..4d0f20b5d2ca 100644
--- a/lib/galaxy/managers/markdown_parse.py
+++ b/lib/galaxy/managers/markdown_parse.py
@@ -30,6 +30,16 @@ class DynamicArguments:
"history_dataset_display": ["input", "output", "history_dataset_id"],
"history_dataset_embedded": ["input", "output", "history_dataset_id"],
"history_dataset_as_image": ["input", "output", "history_dataset_id", "path"],
+ "history_dataset_as_table": [
+ "input",
+ "output",
+ "history_dataset_id",
+ "path",
+ "title",
+ "footer",
+ "show_column_headers",
+ "compact",
+ ],
"history_dataset_peek": ["input", "output", "history_dataset_id"],
"history_dataset_info": ["input", "output", "history_dataset_id"],
"history_dataset_link": ["input", "output", "history_dataset_id", "path", "label"],
diff --git a/lib/galaxy/managers/markdown_util.py b/lib/galaxy/managers/markdown_util.py
index 3523031283cf..9ef57141375e 100644
--- a/lib/galaxy/managers/markdown_util.py
+++ b/lib/galaxy/managers/markdown_util.py
@@ -137,6 +137,10 @@ def _remap(container, line):
_check_object(object_id, line)
hda = hda_manager.get_accessible(object_id, trans.user)
rval = self.handle_dataset_as_image(line, hda)
+ elif container == "history_dataset_as_table":
+ _check_object(object_id, line)
+ hda = hda_manager.get_accessible(object_id, trans.user)
+ rval = self.handle_dataset_as_table(line, hda)
elif container == "history_dataset_peek":
_check_object(object_id, line)
hda = hda_manager.get_accessible(object_id, trans.user)
@@ -251,6 +255,10 @@ def handle_dataset_display(self, line, hda):
def handle_dataset_as_image(self, line, hda):
pass
+ @abc.abstractmethod
+ def handle_dataset_as_table(self, line, hda):
+ pass
+
@abc.abstractmethod
def handle_dataset_peek(self, line, hda):
pass
@@ -411,6 +419,9 @@ def handle_history_link(self, line, history):
def handle_dataset_as_image(self, line, hda):
pass
+ def handle_dataset_as_table(self, line, hda):
+ pass
+
def handle_job_metrics(self, line, job):
pass
@@ -538,6 +549,14 @@ def _embed_image(self, name: str, image_type: str, image_data: bytes):
base64_image_data = base64.b64encode(image_data).decode("utf-8")
return f"![{name}](data:image/{image_type};base64,{base64_image_data})"
+ def handle_dataset_as_table(self, line, hda):
+ # TODO: this form of the rendering doesn't do anything special with advanced
+ # options yet but could easily be modified in the future. show_column_headers,
+ # compact, title, and footer should be handled in here to bring the PDF and the
+ # web rendering closer.
+ rval = self.handle_dataset_embedded(line, hda)
+ return rval
+
def handle_history_link(self, line, history):
if history:
content = literal_via_fence(history.name)
diff --git a/lib/galaxy/managers/workflows.py b/lib/galaxy/managers/workflows.py
index 8bbc703056b0..e882f424c214 100644
--- a/lib/galaxy/managers/workflows.py
+++ b/lib/galaxy/managers/workflows.py
@@ -1129,6 +1129,7 @@ def do_inputs(inputs, values, prefix, step, other_values=None):
for step in workflow.steps:
step_dict = {}
step_dict["order_index"] = step.order_index
+ step_dict["type"] = step.type
if step.annotations:
step_dict["annotation"] = step.annotations[0].annotation
try:
@@ -1139,6 +1140,8 @@ def do_inputs(inputs, values, prefix, step, other_values=None):
continue
if step.type == "tool":
tool = trans.app.toolbox.get_tool(step.tool_id, step.tool_version)
+ step_dict["tool_id"] = step.tool_id
+ step_dict["tool_version"] = step.tool_version
step_dict["label"] = step.label or tool.name
step_dict["inputs"] = do_inputs(tool.inputs, step.state.inputs, "", step)
elif step.type == "subworkflow":
diff --git a/lib/galaxy/model/__init__.py b/lib/galaxy/model/__init__.py
index 8a90c78ffb11..f341dd308073 100644
--- a/lib/galaxy/model/__init__.py
+++ b/lib/galaxy/model/__init__.py
@@ -1822,6 +1822,7 @@ def to_dict(self, view="collection", system_details=False):
else:
rval = super().to_dict(view=view)
rval["tool_id"] = self.tool_id
+ rval["tool_version"] = self.tool_version
rval["history_id"] = self.history_id
if system_details or view == "admin_job_list":
# System level details that only admins should have.