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" ;
36import { computed , onUnmounted , ref , watch } from " vue" ;
47
58import type { WorkflowInvocationElementView } from " @/api/invocations" ;
@@ -55,8 +58,6 @@ const computedExpanded = computed({
5558
5659const workflowStepType = computed (() => props .workflowStep .type );
5760
58- const isDataStep = computed (() => [" data_input" , " data_collection_input" ].includes (workflowStepType .value ));
59-
6061const invocationInput = computed (() => props .invocation .inputs [props .workflowStep .id ]);
6162
6263const 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+
7076const isReady = computed (() => props .invocation .steps .length > 0 );
7177
7278const 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