Skip to content

Commit d20d0a6

Browse files
add tabs to WorkflowInvocationStep, to separate jobs and outputs
1 parent 00f47d3 commit d20d0a6

1 file changed

Lines changed: 90 additions & 47 deletions

File tree

client/src/components/WorkflowInvocationState/WorkflowInvocationStep.vue

Lines changed: 90 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
<script setup lang="ts">
2-
import { BAlert } from "bootstrap-vue";
2+
import { faTimesCircle } from "@fortawesome/free-regular-svg-icons";
3+
import { faInfoCircle } from "@fortawesome/free-solid-svg-icons";
4+
import { FontAwesomeIcon } from "@fortawesome/vue-fontawesome";
5+
import { BAlert, BTab, BTabs } from "bootstrap-vue";
36
import { computed, onUnmounted, ref, watch } from "vue";
47
58
import type { WorkflowInvocationElementView } from "@/api/invocations";
@@ -55,8 +58,6 @@ const computedExpanded = computed({
5558
5659
const workflowStepType = computed(() => props.workflowStep.type);
5760
58-
const isDataStep = computed(() => ["data_input", "data_collection_input"].includes(workflowStepType.value));
59-
6061
const invocationInput = computed(() => props.invocation.inputs[props.workflowStep.id]);
6162
6263
const invocationStep = computed(() => props.invocation.steps[props.workflowStep.id]);
@@ -67,6 +68,11 @@ const stepDetails = computed(() =>
6768
invocationStepId.value ? invocationStore.getInvocationStepById(invocationStepId.value) : null,
6869
);
6970
71+
const hasOutputDatasets = computed(() => stepDetails.value && Object.values(stepDetails.value.outputs).length > 0);
72+
const hasOutputCollections = computed(
73+
() => stepDetails.value && Object.values(stepDetails.value.output_collections).length > 0,
74+
);
75+
7076
const isReady = computed(() => props.invocation.steps.length > 0);
7177
7278
const loading = computed(() => {
@@ -120,13 +126,30 @@ async function pollStepUntilTerminal() {
120126
}
121127
}
122128
123-
const jobStepHeading = computed(() => {
124-
if (stepDetails.value?.jobs && stepDetails.value.jobs.length > 1) {
125-
return "Jobs (Click on any job to view its details)";
126-
} else if (stepDetails.value?.jobs?.length === 1) {
127-
return "Job";
129+
const jobsTabIcon = computed(() =>
130+
hasOutputDatasets.value || hasOutputCollections.value ? faInfoCircle : faTimesCircle,
131+
);
132+
133+
const jobsTabTitle = computed(() => {
134+
if (hasOutputDatasets.value || hasOutputCollections.value) {
135+
if (stepDetails.value?.jobs && stepDetails.value.jobs.length > 1) {
136+
return "Jobs (Click on any job to view its details)";
137+
} else if (stepDetails.value?.jobs?.length === 1) {
138+
return "Job";
139+
}
140+
}
141+
return "No jobs";
142+
});
143+
144+
const outputsTabTitle = computed(() => {
145+
if (hasOutputDatasets.value && hasOutputCollections.value) {
146+
return "Outputs";
147+
} else if (hasOutputDatasets.value) {
148+
return "Output Datasets";
149+
} else if (hasOutputCollections.value) {
150+
return "Output Collections";
128151
} else {
129-
return "No jobs";
152+
return "No outputs";
130153
}
131154
});
132155
@@ -170,48 +193,22 @@ onUnmounted(() => {
170193
<BAlert v-else-if="!stepDetails" variant="info" show> Unable to load step details. </BAlert>
171194

172195
<div v-else>
173-
<div
174-
v-if="!isDataStep && Object.values(stepDetails.outputs).length > 0"
175-
class="invocation-step-output-details">
176-
<Heading size="md" separator>Output Datasets</Heading>
177-
<div v-for="(value, name) in stepDetails.outputs" :key="value.id">
178-
<b>{{ name }}</b>
179-
<GenericHistoryItem :item-id="value.id" :item-src="value.src" />
180-
</div>
181-
</div>
182-
183-
<div
184-
v-if="!isDataStep && Object.values(stepDetails.output_collections).length > 0"
185-
class="invocation-step-output-collection-details">
186-
<Heading size="md" separator>Output Dataset Collections</Heading>
187-
<div v-for="(value, name) in stepDetails.output_collections" :key="value.id">
188-
<b>{{ name }}</b>
189-
<GenericHistoryItem :item-id="value.id" :item-src="value.src" />
190-
</div>
191-
</div>
192-
193-
<div class="portlet-body" style="width: 100%; overflow-x: auto">
194-
<div
195-
v-if="workflowStepType == 'tool'"
196-
class="invocation-step-job-details"
197-
:open="inGraphView">
198-
<Heading size="md" separator>{{ jobStepHeading }}</Heading>
199-
<JobStep v-if="stepDetails.jobs?.length" class="mt-1" :jobs="stepDetails.jobs" />
200-
<BAlert v-else v-localize variant="info" show>This step has no jobs</BAlert>
201-
</div>
202-
203-
<ParameterStep
204-
v-else-if="workflowStepType == 'parameter_input'"
205-
:parameters="paramInput ? [paramInput] : []" />
206-
196+
<ParameterStep
197+
v-if="workflowStepType === 'parameter_input'"
198+
:parameters="paramInput ? [paramInput] : []" />
199+
200+
<template
201+
v-else-if="
202+
workflowStepType === 'data_input' || workflowStepType === 'data_collection_input'
203+
">
207204
<GenericHistoryItem
208-
v-else-if="
209-
isDataStep && props.invocation.inputs && invocationInput && invocationInput.id
210-
"
205+
v-if="invocationInput && invocationInput.id"
211206
:item-id="invocationInput.id"
212207
:item-src="invocationInput.src" />
208+
</template>
213209

214-
<div v-else-if="workflowStepType == 'subworkflow'">
210+
<div v-else>
211+
<div v-if="workflowStepType === 'subworkflow'">
215212
<div v-if="!stepDetails.subworkflow_invocation_id">
216213
Workflow invocation for this step is not yet scheduled.
217214
<template v-if="props.workflowStep">
@@ -242,6 +239,52 @@ onUnmounted(() => {
242239

243240
<SubworkflowAlert v-else :invocation-id="stepDetails.subworkflow_invocation_id" />
244241
</div>
242+
243+
<BTabs justified>
244+
<BTab v-if="hasOutputDatasets || hasOutputCollections" :title="outputsTabTitle">
245+
<div v-if="hasOutputDatasets" class="invocation-step-output-details">
246+
<Heading v-if="hasOutputCollections" size="md" separator>
247+
Output Datasets
248+
</Heading>
249+
<div v-for="(value, name) in stepDetails.outputs" :key="value.id">
250+
<b>{{ name }}</b>
251+
<GenericHistoryItem :item-id="value.id" :item-src="value.src" />
252+
</div>
253+
</div>
254+
255+
<div
256+
v-if="hasOutputCollections"
257+
class="invocation-step-output-collection-details">
258+
<Heading v-if="hasOutputDatasets" size="md" separator>
259+
Output Dataset Collections
260+
</Heading>
261+
<div
262+
v-for="(value, name) in stepDetails.output_collections"
263+
:key="value.id">
264+
<b>{{ name }}</b>
265+
<GenericHistoryItem :item-id="value.id" :item-src="value.src" />
266+
</div>
267+
</div>
268+
</BTab>
269+
270+
<BTab
271+
v-if="workflowStepType === 'tool'"
272+
class="portlet-body"
273+
style="width: 100%; overflow-x: auto">
274+
<template v-slot:title>
275+
<FontAwesomeIcon :icon="jobsTabIcon" />
276+
<span v-localize>{{ jobsTabTitle }}</span>
277+
</template>
278+
279+
<div class="invocation-step-job-details" :open="inGraphView">
280+
<JobStep
281+
v-if="stepDetails.jobs?.length"
282+
class="mt-1"
283+
:jobs="stepDetails.jobs" />
284+
<BAlert v-else v-localize variant="info" show>This step has no jobs</BAlert>
285+
</div>
286+
</BTab>
287+
</BTabs>
245288
</div>
246289
</div>
247290
</div>

0 commit comments

Comments
 (0)