fix(editor): Fix layout of binary data preview in the log view (#17584)

This commit is contained in:
Suguru Inoue
2025-07-24 11:57:12 +02:00
committed by GitHub
parent c30dbc6dd4
commit 456c4e8167
5 changed files with 351 additions and 302 deletions

View File

@@ -95,11 +95,11 @@ function closeWindow() {
<style lang="scss"> <style lang="scss">
.binary-data-window { .binary-data-window {
position: absolute; position: absolute;
top: 50px; top: 0;
left: 0; left: 0;
z-index: 10; z-index: 10;
width: 100%; width: 100%;
height: calc(100% - 50px); height: 100%;
background-color: var(--color-run-data-background); background-color: var(--color-run-data-background);
overflow: hidden; overflow: hidden;
text-align: center; text-align: center;
@@ -111,7 +111,7 @@ function closeWindow() {
.binary-data-window-wrapper { .binary-data-window-wrapper {
margin-top: 0.5em; margin-top: 0.5em;
padding: 0 1em; padding: 0 1em;
height: calc(100% - 50px); height: 100%;
.el-row, .el-row,
.el-col { .el-col {

View File

@@ -1,5 +1,4 @@
<script setup lang="ts"> <script setup lang="ts">
import { ViewableMimeTypes } from '@n8n/api-types';
import { useStorage } from '@/composables/useStorage'; import { useStorage } from '@/composables/useStorage';
import { saveAs } from 'file-saver'; import { saveAs } from 'file-saver';
import NodeSettingsHint from '@/components/NodeSettingsHint.vue'; import NodeSettingsHint from '@/components/NodeSettingsHint.vue';
@@ -99,6 +98,7 @@ import RunDataPaginationBar from '@/components/RunDataPaginationBar.vue';
import { parseAiContent } from '@/utils/aiUtils'; import { parseAiContent } from '@/utils/aiUtils';
import { usePostHog } from '@/stores/posthog.store'; import { usePostHog } from '@/stores/posthog.store';
import { I18nT } from 'vue-i18n'; import { I18nT } from 'vue-i18n';
import RunDataBinary from '@/components/RunDataBinary.vue';
const LazyRunDataTable = defineAsyncComponent( const LazyRunDataTable = defineAsyncComponent(
async () => await import('@/components/RunDataTable.vue'), async () => await import('@/components/RunDataTable.vue'),
@@ -220,7 +220,6 @@ const dataSize = ref(0);
const showData = ref(false); const showData = ref(false);
const userEnabledShowData = ref(false); const userEnabledShowData = ref(false);
const outputIndex = ref(0); const outputIndex = ref(0);
const binaryDataDisplayVisible = ref(false);
const binaryDataDisplayData = ref<IBinaryData | null>(null); const binaryDataDisplayData = ref<IBinaryData | null>(null);
const currentPage = ref(1); const currentPage = ref(1);
const pageSize = ref(10); const pageSize = ref(10);
@@ -636,6 +635,10 @@ const hasParsedAiContent = computed(() =>
parsedAiContent.value.some((prr) => prr.parsedContent?.parsed), parsedAiContent.value.some((prr) => prr.parsedContent?.parsed),
); );
const binaryDataDisplayVisible = computed(
() => binaryDataDisplayData.value !== null && props.displayMode === 'binary',
);
function setInputBranchIndex(value: number) { function setInputBranchIndex(value: number) {
if (props.paneType === 'input') { if (props.paneType === 'input') {
outputIndex.value = value; outputIndex.value = value;
@@ -1238,35 +1241,10 @@ function init() {
} }
function closeBinaryDataDisplay() { function closeBinaryDataDisplay() {
binaryDataDisplayVisible.value = false;
binaryDataDisplayData.value = null; binaryDataDisplayData.value = null;
} }
function isViewable(index: number, key: string | number): boolean { function downloadJsonData() {
const { mimeType } = binaryData.value[index][key];
return ViewableMimeTypes.includes(mimeType);
}
function isDownloadable(index: number, key: string | number): boolean {
const { mimeType, fileName } = binaryData.value[index][key];
return !!(mimeType && fileName);
}
async function downloadBinaryData(index: number, key: string | number) {
const { id, data, fileName, fileExtension, mimeType } = binaryData.value[index][key];
if (id) {
const url = workflowsStore.getBinaryUrl(id, 'download', fileName ?? '', mimeType);
saveAs(url, [fileName, fileExtension].join('.'));
return;
} else {
const bufferString = 'data:' + mimeType + ';base64,' + data;
const blob = await fetch(bufferString).then(async (d) => await d.blob());
saveAs(blob, fileName);
}
}
async function downloadJsonData() {
const fileName = (node.value?.name ?? '').replace(/[^\w\d]/g, '_'); const fileName = (node.value?.name ?? '').replace(/[^\w\d]/g, '_');
const blob = new Blob([JSON.stringify(rawInputData.value, null, 2)], { const blob = new Blob([JSON.stringify(rawInputData.value, null, 2)], {
type: 'application/json', type: 'application/json',
@@ -1277,7 +1255,6 @@ async function downloadJsonData() {
function displayBinaryData(index: number, key: string | number) { function displayBinaryData(index: number, key: string | number) {
const { data, mimeType } = binaryData.value[index][key]; const { data, mimeType } = binaryData.value[index][key];
binaryDataDisplayVisible.value = true;
binaryDataDisplayData.value = { binaryDataDisplayData.value = {
node: node.value?.name, node: node.value?.name,
@@ -1413,13 +1390,6 @@ defineExpose({ enterEditMode });
</template> </template>
</N8nCallout> </N8nCallout>
<BinaryDataDisplay
v-if="binaryDataDisplayData"
:window-visible="binaryDataDisplayVisible"
:display-data="binaryDataDisplayData"
@close="closeBinaryDataDisplay"
/>
<div :class="$style.header"> <div :class="$style.header">
<div :class="$style.title"> <div :class="$style.title">
<slot name="header"></slot> <slot name="header"></slot>
@@ -1513,126 +1483,135 @@ defineExpose({ enterEditMode });
<RunDataItemCount v-if="props.compact" v-bind="itemsCountProps" /> <RunDataItemCount v-if="props.compact" v-bind="itemsCountProps" />
</div> </div>
<div v-if="inputSelectLocation === 'header'" :class="$style.inputSelect"> <div v-show="!binaryDataDisplayVisible">
<slot name="input-select"></slot> <div v-if="inputSelectLocation === 'header'" :class="$style.inputSelect">
</div> <slot name="input-select"></slot>
<div
v-if="maxRunIndex > 0 && !displaysMultipleNodes && !props.disableRunIndexSelection"
v-show="!editMode.enabled"
:class="$style.runSelector"
>
<div :class="$style.runSelectorInner">
<slot v-if="inputSelectLocation === 'runs'" name="input-select"></slot>
<N8nSelect
:model-value="runIndex"
:class="$style.runSelectorSelect"
size="small"
teleported
data-test-id="run-selector"
@update:model-value="onRunIndexChange"
@click.stop
>
<template #prepend>{{ i18n.baseText('ndv.output.run') }}</template>
<N8nOption
v-for="option in maxRunIndex + 1"
:key="option"
:label="getRunLabel(option)"
:value="option - 1"
></N8nOption>
</N8nSelect>
<N8nTooltip v-if="canLinkRuns" placement="right">
<template #content>
{{ i18n.baseText(linkedRuns ? 'runData.unlinking.hint' : 'runData.linking.hint') }}
</template>
<N8nIconButton
:icon="linkedRuns ? 'unlink' : 'link'"
:class="['linkRun', linkedRuns ? 'linked' : '']"
text
type="tertiary"
size="small"
data-test-id="link-run"
@click="toggleLinkRuns"
/>
</N8nTooltip>
<slot name="run-info"></slot>
</div> </div>
<ViewSubExecution
v-if="activeTaskMetadata && !(paneType === 'input' && hasInputOverwrite)"
:task-metadata="activeTaskMetadata"
:display-mode="displayMode"
/>
</div>
<slot v-if="!displaysMultipleNodes" name="before-data" /> <div
v-if="maxRunIndex > 0 && !displaysMultipleNodes && !props.disableRunIndexSelection"
v-show="!editMode.enabled"
:class="$style.runSelector"
>
<div :class="$style.runSelectorInner">
<slot v-if="inputSelectLocation === 'runs'" name="input-select"></slot>
<div v-if="props.calloutMessage || $slots['callout-message']" :class="$style.hintCallout"> <N8nSelect
<N8nCallout theme="info" data-test-id="run-data-callout"> :model-value="runIndex"
<slot name="callout-message"> :class="$style.runSelectorSelect"
<N8nText v-n8n-html="props.calloutMessage" size="small"></N8nText> size="small"
</slot> teleported
data-test-id="run-selector"
@update:model-value="onRunIndexChange"
@click.stop
>
<template #prepend>{{ i18n.baseText('ndv.output.run') }}</template>
<N8nOption
v-for="option in maxRunIndex + 1"
:key="option"
:label="getRunLabel(option)"
:value="option - 1"
></N8nOption>
</N8nSelect>
<N8nTooltip v-if="canLinkRuns" placement="right">
<template #content>
{{ i18n.baseText(linkedRuns ? 'runData.unlinking.hint' : 'runData.linking.hint') }}
</template>
<N8nIconButton
:icon="linkedRuns ? 'unlink' : 'link'"
:class="['linkRun', linkedRuns ? 'linked' : '']"
text
type="tertiary"
size="small"
data-test-id="link-run"
@click="toggleLinkRuns"
/>
</N8nTooltip>
<slot name="run-info"></slot>
</div>
<ViewSubExecution
v-if="activeTaskMetadata && !(paneType === 'input' && hasInputOverwrite)"
:task-metadata="activeTaskMetadata"
:display-mode="displayMode"
/>
</div>
<slot v-if="!displaysMultipleNodes" name="before-data" />
<div v-if="props.calloutMessage || $slots['callout-message']" :class="$style.hintCallout">
<N8nCallout theme="info" data-test-id="run-data-callout">
<slot name="callout-message">
<N8nText v-n8n-html="props.calloutMessage" size="small"></N8nText>
</slot>
</N8nCallout>
</div>
<NodeSettingsHint v-if="props.paneType === 'output'" :node="node" />
<N8nCallout
v-for="hint in getNodeHints()"
:key="hint.message"
:class="$style.hintCallout"
:theme="hint.type || 'info'"
data-test-id="node-hint"
>
<N8nText v-n8n-html="hint.message" size="small"></N8nText>
</N8nCallout> </N8nCallout>
</div>
<NodeSettingsHint v-if="props.paneType === 'output'" :node="node" />
<N8nCallout
v-for="hint in getNodeHints()"
:key="hint.message"
:class="$style.hintCallout"
:theme="hint.type || 'info'"
data-test-id="node-hint"
>
<N8nText v-n8n-html="hint.message" size="small"></N8nText>
</N8nCallout>
<div <div
v-if="maxOutputIndex > 0 && branches.length > 1 && !displaysMultipleNodes" v-if="maxOutputIndex > 0 && branches.length > 1 && !displaysMultipleNodes"
:class="$style.outputs" :class="$style.outputs"
data-test-id="branches" data-test-id="branches"
> >
<slot v-if="inputSelectLocation === 'outputs'" name="input-select"></slot> <slot v-if="inputSelectLocation === 'outputs'" name="input-select"></slot>
<ViewSubExecution <ViewSubExecution
v-if="activeTaskMetadata && !(paneType === 'input' && hasInputOverwrite)" v-if="activeTaskMetadata && !(paneType === 'input' && hasInputOverwrite)"
:task-metadata="activeTaskMetadata" :task-metadata="activeTaskMetadata"
:display-mode="displayMode" :display-mode="displayMode"
/> />
<div :class="$style.tabs"> <div :class="$style.tabs">
<N8nTabs <N8nTabs
size="small" size="small"
:model-value="currentOutputIndex" :model-value="currentOutputIndex"
:options="branches" :options="branches"
@update:model-value="onBranchChange" @update:model-value="onBranchChange"
/>
</div>
</div>
<div
v-else-if="
!props.compact &&
hasNodeRun &&
!isSearchInSchemaView &&
((dataCount > 0 && maxRunIndex === 0) || search) &&
!isArtificialRecoveredEventItem &&
!displaysMultipleNodes
"
v-show="!editMode.enabled"
:class="$style.itemsCount"
data-test-id="ndv-items-count"
>
<slot v-if="inputSelectLocation === 'items'" name="input-select"></slot>
<RunDataItemCount v-bind="itemsCountProps" />
<ViewSubExecution
v-if="activeTaskMetadata && !(paneType === 'input' && hasInputOverwrite)"
:task-metadata="activeTaskMetadata"
:display-mode="displayMode"
/> />
</div> </div>
</div> </div>
<div
v-else-if="
!props.compact &&
hasNodeRun &&
!isSearchInSchemaView &&
((dataCount > 0 && maxRunIndex === 0) || search) &&
!isArtificialRecoveredEventItem &&
!displaysMultipleNodes
"
v-show="!editMode.enabled"
:class="$style.itemsCount"
data-test-id="ndv-items-count"
>
<slot v-if="inputSelectLocation === 'items'" name="input-select"></slot>
<RunDataItemCount v-bind="itemsCountProps" />
<ViewSubExecution
v-if="activeTaskMetadata && !(paneType === 'input' && hasInputOverwrite)"
:task-metadata="activeTaskMetadata"
:display-mode="displayMode"
/>
</div>
<div ref="dataContainerRef" :class="$style.dataContainer" data-test-id="ndv-data-container"> <div ref="dataContainerRef" :class="$style.dataContainer" data-test-id="ndv-data-container">
<BinaryDataDisplay
v-if="binaryDataDisplayData"
:window-visible="binaryDataDisplayVisible"
:display-data="binaryDataDisplayData"
@close="closeBinaryDataDisplay"
/>
<div <div
v-if="isExecuting && !isWaitNodeWaiting" v-if="isExecuting && !isWaitNodeWaiting"
:class="[$style.center, $style.executingMessage]" :class="[$style.center, $style.executingMessage]"
@@ -1912,91 +1891,12 @@ defineExpose({ enterEditMode });
/> />
</Suspense> </Suspense>
<div v-else-if="displayMode === 'binary' && binaryData.length === 0" :class="$style.center"> <RunDataBinary
<N8nText align="center" tag="div">{{ i18n.baseText('runData.noBinaryDataFound') }}</N8nText> v-else-if="displayMode === 'binary'"
</div> :binary-data="binaryData"
@preview="displayBinaryData"
/>
<div v-else-if="displayMode === 'binary'" :class="$style.dataDisplay">
<div v-for="(binaryDataEntry, index) in binaryData" :key="index">
<div v-if="binaryData.length > 1" :class="$style.binaryIndex">
<div>
{{ index + 1 }}
</div>
</div>
<div :class="$style.binaryRow">
<div
v-for="(binaryData, key) in binaryDataEntry"
:key="index + '_' + key"
:class="$style.binaryCell"
>
<div :data-test-id="'ndv-binary-data_' + index">
<div :class="$style.binaryHeader">
{{ key }}
</div>
<div v-if="binaryData.fileName">
<div>
<N8nText size="small" :bold="true"
>{{ i18n.baseText('runData.fileName') }}:
</N8nText>
</div>
<div :class="$style.binaryValue">{{ binaryData.fileName }}</div>
</div>
<div v-if="binaryData.directory">
<div>
<N8nText size="small" :bold="true"
>{{ i18n.baseText('runData.directory') }}:
</N8nText>
</div>
<div :class="$style.binaryValue">{{ binaryData.directory }}</div>
</div>
<div v-if="binaryData.fileExtension">
<div>
<N8nText size="small" :bold="true"
>{{ i18n.baseText('runData.fileExtension') }}:</N8nText
>
</div>
<div :class="$style.binaryValue">{{ binaryData.fileExtension }}</div>
</div>
<div v-if="binaryData.mimeType">
<div>
<N8nText size="small" :bold="true"
>{{ i18n.baseText('runData.mimeType') }}:
</N8nText>
</div>
<div :class="$style.binaryValue">{{ binaryData.mimeType }}</div>
</div>
<div v-if="binaryData.fileSize">
<div>
<N8nText size="small" :bold="true"
>{{ i18n.baseText('runData.fileSize') }}:
</N8nText>
</div>
<div :class="$style.binaryValue">{{ binaryData.fileSize }}</div>
</div>
<div :class="$style.binaryButtonContainer">
<N8nButton
v-if="isViewable(index, key)"
size="small"
:label="i18n.baseText('runData.showBinaryData')"
data-test-id="ndv-view-binary-data"
@click="displayBinaryData(index, key)"
/>
<N8nButton
v-if="isDownloadable(index, key)"
size="small"
type="secondary"
:label="i18n.baseText('runData.downloadBinaryData')"
data-test-id="ndv-download-binary-data"
@click="downloadBinaryData(index, key)"
/>
</div>
</div>
</div>
</div>
</div>
</div>
<div v-else-if="!hasNodeRun" :class="$style.center"> <div v-else-if="!hasNodeRun" :class="$style.center">
<slot name="node-not-run"></slot> <slot name="node-not-run"></slot>
</div> </div>
@@ -2187,67 +2087,6 @@ defineExpose({ enterEditMode });
margin-left: auto; margin-left: auto;
} }
.binaryIndex {
display: block;
padding: var(--spacing-2xs);
font-size: var(--font-size-2xs);
> * {
display: inline-block;
width: 30px;
height: 30px;
line-height: 30px;
border-radius: var(--border-radius-base);
text-align: center;
background-color: var(--color-foreground-xdark);
font-weight: var(--font-weight-bold);
color: var(--color-text-xlight);
}
}
.binaryRow {
display: inline-flex;
font-size: var(--font-size-2xs);
}
.binaryCell {
display: inline-block;
width: 300px;
overflow: hidden;
background-color: var(--color-foreground-xlight);
margin-right: var(--ndv-spacing);
margin-bottom: var(--ndv-spacing);
border-radius: var(--border-radius-base);
border: var(--border-base);
padding: var(--ndv-spacing);
}
.binaryHeader {
color: $color-primary;
font-weight: var(--font-weight-bold);
font-size: 1.2em;
padding-bottom: var(--spacing-2xs);
margin-bottom: var(--spacing-2xs);
border-bottom: 1px solid var(--color-text-light);
}
.binaryButtonContainer {
margin-top: 1.5em;
display: flex;
flex-direction: row;
justify-content: center;
> * {
flex-grow: 0;
margin-right: var(--spacing-3xs);
}
}
.binaryValue {
white-space: initial;
word-wrap: break-word;
}
.displayModes { .displayModes {
display: flex; display: flex;
justify-content: flex-end; justify-content: flex-end;

View File

@@ -0,0 +1,201 @@
<script setup lang="ts">
import { saveAs } from 'file-saver';
import { useWorkflowsStore } from '@/stores/workflows.store';
import { ViewableMimeTypes } from '@n8n/api-types';
import { useI18n } from '@n8n/i18n';
import type { IBinaryKeyData } from 'n8n-workflow';
import { N8nButton, N8nText } from '@n8n/design-system';
const { binaryData } = defineProps<{ binaryData: IBinaryKeyData[] }>();
const emit = defineEmits<{ preview: [index: number, key: string | number] }>();
const i18n = useI18n();
const workflowsStore = useWorkflowsStore();
function isViewable(index: number, key: string | number): boolean {
const { mimeType } = binaryData[index][key];
return ViewableMimeTypes.includes(mimeType);
}
function isDownloadable(index: number, key: string | number): boolean {
const { mimeType, fileName } = binaryData[index][key];
return !!(mimeType && fileName);
}
async function downloadBinaryData(index: number, key: string | number) {
const { id, data, fileName, fileExtension, mimeType } = binaryData[index][key];
if (id) {
const url = workflowsStore.getBinaryUrl(id, 'download', fileName ?? '', mimeType);
saveAs(url, [fileName, fileExtension].join('.'));
return;
} else {
const bufferString = 'data:' + mimeType + ';base64,' + data;
const blob = await fetch(bufferString).then(async (d) => await d.blob());
saveAs(blob, fileName);
}
}
</script>
<template>
<div :class="$style.component">
<N8nText v-if="binaryData.length === 0" align="center" tag="div">
{{ i18n.baseText('runData.noBinaryDataFound') }}
</N8nText>
<div v-for="(binaryDataEntry, index) in binaryData" :key="index">
<div v-if="binaryData.length > 1" :class="$style.binaryIndex">
<div>
{{ index + 1 }}
</div>
</div>
<div :class="$style.binaryRow">
<div
v-for="(data, key) in binaryDataEntry"
:key="index + '_' + key"
:class="$style.binaryCell"
>
<div :data-test-id="'ndv-binary-data_' + index">
<div :class="$style.binaryHeader">
{{ key }}
</div>
<div v-if="data.fileName">
<div>
<N8nText size="small" :bold="true"
>{{ i18n.baseText('runData.fileName') }}:
</N8nText>
</div>
<div :class="$style.binaryValue">{{ data.fileName }}</div>
</div>
<div v-if="data.directory">
<div>
<N8nText size="small" :bold="true"
>{{ i18n.baseText('runData.directory') }}:
</N8nText>
</div>
<div :class="$style.binaryValue">{{ data.directory }}</div>
</div>
<div v-if="data.fileExtension">
<div>
<N8nText size="small" :bold="true">
{{ i18n.baseText('runData.fileExtension') }}:
</N8nText>
</div>
<div :class="$style.binaryValue">{{ data.fileExtension }}</div>
</div>
<div v-if="data.mimeType">
<div>
<N8nText size="small" :bold="true">
{{ i18n.baseText('runData.mimeType') }}:
</N8nText>
</div>
<div :class="$style.binaryValue">{{ data.mimeType }}</div>
</div>
<div v-if="data.fileSize">
<div>
<N8nText size="small" :bold="true">
{{ i18n.baseText('runData.fileSize') }}:
</N8nText>
</div>
<div :class="$style.binaryValue">{{ data.fileSize }}</div>
</div>
<div :class="$style.binaryButtonContainer">
<N8nButton
v-if="isViewable(index, key)"
size="small"
:label="i18n.baseText('runData.showBinaryData')"
data-test-id="ndv-view-binary-data"
@click="emit('preview', index, key)"
/>
<N8nButton
v-if="isDownloadable(index, key)"
size="small"
type="secondary"
:label="i18n.baseText('runData.downloadBinaryData')"
data-test-id="ndv-download-binary-data"
@click="downloadBinaryData(index, key)"
/>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
<style lang="scss" module>
.component {
position: absolute;
top: 0;
left: 0;
padding: 0 var(--ndv-spacing) var(--spacing-3xl) var(--ndv-spacing);
right: 0;
overflow-y: auto;
line-height: var(--font-line-height-xloose);
word-break: normal;
height: 100%;
}
.binaryIndex {
display: block;
padding: var(--spacing-2xs);
font-size: var(--font-size-2xs);
> * {
display: inline-block;
width: 30px;
height: 30px;
line-height: 30px;
border-radius: var(--border-radius-base);
text-align: center;
background-color: var(--color-foreground-xdark);
font-weight: var(--font-weight-bold);
color: var(--color-text-xlight);
}
}
.binaryRow {
display: inline-flex;
font-size: var(--font-size-2xs);
}
.binaryCell {
display: inline-block;
width: 300px;
overflow: hidden;
background-color: var(--color-foreground-xlight);
margin-right: var(--ndv-spacing);
margin-bottom: var(--ndv-spacing);
border-radius: var(--border-radius-base);
border: var(--border-base);
padding: var(--ndv-spacing);
}
.binaryHeader {
color: $color-primary;
font-weight: var(--font-weight-bold);
font-size: 1.2em;
padding-bottom: var(--spacing-2xs);
margin-bottom: var(--spacing-2xs);
border-bottom: 1px solid var(--color-text-light);
}
.binaryButtonContainer {
margin-top: 1.5em;
display: flex;
flex-direction: row;
justify-content: center;
> * {
flex-grow: 0;
margin-right: var(--spacing-3xs);
}
}
.binaryValue {
white-space: initial;
word-wrap: break-word;
}
</style>

View File

@@ -7,7 +7,6 @@ exports[`InputPanel > should render 1`] = `
data-test-id="ndv-input-panel" data-test-id="ndv-input-panel"
data-v-2e5cd75c="" data-v-2e5cd75c=""
> >
<!--v-if-->
<!--v-if--> <!--v-if-->
<div <div
class="header" class="header"
@@ -161,19 +160,24 @@ exports[`InputPanel > should render 1`] = `
</div> </div>
<!--v-if--> <!--v-if-->
</div> </div>
<!--v-if--> <div
<!--v-if--> data-v-2e5cd75c=""
<!--v-if--> >
<!--v-if--> <!--v-if-->
<!--v-if--> <!--v-if-->
<!--v-if-->
<!--v-if-->
<!--v-if--> <!--v-if-->
<!--v-if-->
</div>
<div <div
class="dataContainer" class="dataContainer"
data-test-id="ndv-data-container" data-test-id="ndv-data-container"
data-v-2e5cd75c="" data-v-2e5cd75c=""
> >
<!--v-if-->
<!----> <!---->
</div> </div>
<!--v-if--> <!--v-if-->

View File

@@ -75,6 +75,7 @@ function handleChangeDisplayMode(value: IRunDataDisplayMode) {
v-if="runDataProps" v-if="runDataProps"
v-bind="runDataProps" v-bind="runDataProps"
:key="`run-data${pipWindow ? '-pip' : ''}`" :key="`run-data${pipWindow ? '-pip' : ''}`"
:class="$style.component"
:workflow="logEntry.workflow" :workflow="logEntry.workflow"
:workflow-execution="logEntry.execution" :workflow-execution="logEntry.execution"
:too-much-data-title="locale.baseText('ndv.output.tooMuchData.title')" :too-much-data-title="locale.baseText('ndv.output.tooMuchData.title')"
@@ -130,6 +131,10 @@ function handleChangeDisplayMode(value: IRunDataDisplayMode) {
</template> </template>
<style lang="scss" module> <style lang="scss" module>
.component {
--color-run-data-background: var(--color-background-light);
}
.title { .title {
text-transform: uppercase; text-transform: uppercase;
letter-spacing: 3px; letter-spacing: 3px;