diff --git a/client/src/components/Workflow/Editor/NodeOutput.vue b/client/src/components/Workflow/Editor/NodeOutput.vue index 0d522a1f583e..621dc268ba9d 100644 --- a/client/src/components/Workflow/Editor/NodeOutput.vue +++ b/client/src/components/Workflow/Editor/NodeOutput.vue @@ -90,9 +90,9 @@ const visibleHint = computed(() => { } }); const label = computed(() => { - const activeLabel = workflowOutput.value?.label || props.output.name; - return `${activeLabel} (${extensions.value.join(", ")})`; + return workflowOutput.value?.label || props.output.name; }); + const rowClass = computed(() => { const classes = ["form-row", "dataRow", "output-data-row"]; if ("valid" in props.output && props.output?.valid === false) { @@ -129,7 +129,7 @@ function onToggleActive() { (workflowOutput) => workflowOutput.output_name !== output.value.name ); } else { - stepWorkflowOutputs.push({ output_name: output.value.name }); + stepWorkflowOutputs.push({ output_name: output.value.name, label: output.value.name }); } stepStore.updateStep({ ...step, workflow_outputs: stepWorkflowOutputs }); } @@ -269,6 +269,22 @@ const outputDetails = computed(() => { return outputType; }); +const isDuplicateLabel = computed(() => { + const duplicateLabels = stepStore.duplicateLabels; + return Boolean(label.value && duplicateLabels.has(label.value)); +}); + +const labelClass = computed(() => { + if (isDuplicateLabel.value) { + return "alert-info"; + } + return null; +}); + +const labelToolTipTitle = computed(() => { + return `Output label '${workflowOutput.value?.label}' is not unique`; +}); + onBeforeUnmount(() => { stateStore.deleteOutputTerminalPosition(props.stepId, props.output.name); }); @@ -304,7 +320,17 @@ const removeTagsAction = computed(() => { @click="onToggleVisible"> - {{ label }} + + + {{ label }} + + ({{ extensions.join(", ") }}) +
= new Set(); + const labels: Set = new Set(); + Object.values(state.steps).forEach((step) => { + if (step.workflow_outputs?.length) { + step.workflow_outputs.forEach((workflowOutput) => { + if (workflowOutput.label) { + if (labels.has(workflowOutput.label)) { + duplicateLabels.add(workflowOutput.label); + } + labels.add(workflowOutput.label); + } + }); + } + }); + return duplicateLabels; + }, }, actions: { addStep(newStep: NewStep): Step { diff --git a/client/src/utils/navigation/navigation.yml b/client/src/utils/navigation/navigation.yml index bba88287c1b7..31427fafb096 100644 --- a/client/src/utils/navigation/navigation.yml +++ b/client/src/utils/navigation/navigation.yml @@ -671,7 +671,7 @@ workflow_editor: clone: '${_} .node-clone' output_data_row: type: xpath - selector: '//div[contains(@class, "output-data-row") and contains(string(), "${output_name} (${extension})")]' + selector: '//div[@data-output-name="${output_name}"]//span[contains(text(), "(${extension})")]' output_terminal: "${_} [output-name='${name}']" input_terminal: "${_} [input-name='${name}']" input_mapping_icon: "${_} [input-name='${name}'].multiple"