fix(editor): Improve workflow diff components (#18018)

This commit is contained in:
Csaba Tuncsik
2025-08-06 18:53:35 +02:00
committed by GitHub
parent 9cb5754f33
commit 95ed3c5c92
5 changed files with 166 additions and 40 deletions

View File

@@ -4,6 +4,17 @@
// Primary tokens
--color-danger: var(--prim-color-alt-k);
// Diff colors (dark theme overrides)
--diff-new: #38cb7a;
--diff-new-light: #43674f;
--diff-new-faint: #3a463e;
--diff-modified: #d6a625;
--diff-modified-light: #6a5c38;
--diff-modified-faint: #464236;
--diff-del: #fb887a;
--diff-del-light: #7a524e;
--diff-del-faint: #4d3e3d;
// Text
--color-text-dark: var(--prim-gray-40);
--color-text-base: var(--prim-gray-200);

View File

@@ -42,6 +42,17 @@
--color-danger-tint-1: var(--prim-color-alt-c-tint-400);
--color-danger-tint-2: var(--prim-color-alt-c-tint-450);
// Diff colors
--diff-new: #0eab54;
--diff-new-light: #b4efc4;
--diff-new-faint: #ddfbe7;
--diff-modified: #bf941f;
--diff-modified-light: #f3dca1;
--diff-modified-faint: #fbf1d4;
--diff-del: #f51f32;
--diff-del-light: #fad3d0;
--diff-del-faint: #ffedec;
// Text
--color-text-dark: var(--prim-gray-740);
--color-text-base: var(--prim-gray-540);

View File

@@ -24,11 +24,123 @@ const props = withDefaults(
<CodeDiff v-bind="props" class="code-diff" />
</template>
<style scoped>
<style lang="scss">
/* Diff colors are now centralized in @n8n/design-system tokens */
.code-diff {
height: 100%;
margin: 0;
border: none;
border-radius: 0;
// Dark theme support for v-code-diff
[data-theme='dark'] & {
// Main container and wrapper (primary background)
background: var(--color-background-light) !important; // Dark background in dark theme
color: var(--color-text-dark) !important; // In dark theme: light text
// Target all possible wrapper elements
> div,
.v-code-diff,
.v-code-diff-wrapper,
.code-diff-wrapper,
.diff-wrapper {
background: var(--color-background-light) !important;
}
// Code diff view wrapper
.code-diff-view {
background: var(--color-background-light) !important; // Dark background
color: var(--color-text-dark) !important;
}
// Main table wrapper
.diff-table {
background: var(--color-background-light) !important; // Dark background
color: var(--color-text-dark) !important;
}
// Line numbers (slightly emphasized background)
.blob-num {
background: var(--color-background-darker) !important; // In dark theme: even lighter gray
color: var(--color-text-light) !important; // Muted text
border-color: var(--color-foreground-base) !important;
}
// Context lines (unchanged code - dark background for better contrast)
.blob-num-context {
background: var(--color-background-light) !important; // Dark background in dark theme
color: var(--color-text-light) !important; // Muted text
}
.blob-code-context {
background: var(--color-background-light) !important; // Dark background in dark theme
color: var(--color-text-dark) !important; // Primary text
}
// Added lines (insertions)
.blob-num-addition {
background: var(--diff-new-light) !important;
color: var(--color-text-xlight) !important;
border-color: var(--diff-new) !important;
}
.blob-code-addition {
background: var(--diff-new-faint) !important;
color: var(--color-text-xlight) !important;
}
// Deleted lines
.blob-num-deletion {
background: var(--diff-del-light) !important;
color: var(--color-text-xlight) !important;
border-color: var(--diff-del) !important;
}
.blob-code-deletion {
background: var(--diff-del-faint) !important;
color: var(--color-text-xlight) !important;
}
// Hunk headers
.blob-num-hunk,
.blob-code-hunk {
background: var(--color-background-medium) !important;
color: var(--color-text-base) !important;
}
// Code markers and inner content
.blob-code-inner {
color: var(--color-text-dark) !important;
}
// Syntax highlighting overrides for dark theme
.hljs-attr {
color: #79c0ff !important;
}
.hljs-string {
color: #a5d6ff !important;
}
.hljs-number {
color: #79c0ff !important;
}
.hljs-punctuation {
color: var(--color-text-light) !important;
}
.hljs-keyword,
.hljs-literal {
color: #ff7b72 !important;
}
// Character-level diff highlighting
.x {
background: rgba(255, 255, 255, 0.1) !important;
color: inherit !important;
}
}
}
</style>

View File

@@ -21,9 +21,6 @@ function onResize({ width }: { width: number }) {
}
const outputFormat = ref<'side-by-side' | 'line-by-line'>('line-by-line');
function toggleOutputFormat() {
outputFormat.value = outputFormat.value === 'line-by-line' ? 'side-by-side' : 'line-by-line';
}
const emit = defineEmits<{
close: [];
@@ -44,22 +41,22 @@ const emit = defineEmits<{
style="display: flex; flex-direction: row; align-items: center; gap: 8px; padding: 12px 10px"
>
<NodeIcon class="ml-xs" :node-type :size="16" />
<N8nHeading size="small" color="text-dark" bold>
<N8nHeading size="small" color="text-dark" bold :class="$style.nodeTitle">
{{ node.name }}
</N8nHeading>
<N8nIconButton
icon="file-diff"
icon="x"
type="secondary"
text
class="ml-auto"
@click="toggleOutputFormat"
@click="emit('close')"
></N8nIconButton>
<N8nIconButton icon="x" type="secondary" text @click="emit('close')"></N8nIconButton>
</div>
<slot v-bind="{ outputFormat, toggleOutputFormat }" />
<slot v-bind="{ outputFormat }" />
</N8nResizeWrapper>
</template>
<style module>
<style module lang="scss">
.workflowDiffAside {
width: calc(v-bind(panelWidth) * 1px);
display: flex;
@@ -68,4 +65,11 @@ const emit = defineEmits<{
border-left: 1px solid var(--color-foreground-base);
border-top: 1px solid var(--color-foreground-base);
}
.nodeTitle {
flex: 1;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
</style>

View File

@@ -399,7 +399,7 @@ const modifiers = [
>
<DiffBadge :type="change.status" />
<NodeIcon :node-type="change.type" :size="16" class="ml-2xs mr-4xs" />
{{ change.node.name }}
<span :class="$style.nodeName">{{ change.node.name }}</span>
</ElDropdownItem>
</ul>
<ul v-if="activeTab === 'connectors'" :class="$style.changes">
@@ -407,7 +407,7 @@ const modifiers = [
<div>
<DiffBadge :type="change[1].status" />
</div>
<div style="flex: 1">
<div style="flex: 1; min-width: 0">
<ul :class="$style.changesNested">
<ElDropdownItem
:class="{
@@ -424,7 +424,9 @@ const modifiers = [
:size="16"
class="ml-2xs mr-4xs"
/>
{{ change[1].connection.source?.name }}
<span :class="$style.nodeName">{{
change[1].connection.source?.name
}}</span>
</ElDropdownItem>
<div :class="$style.separator"></div>
<ElDropdownItem
@@ -442,7 +444,9 @@ const modifiers = [
:size="16"
class="ml-2xs mr-4xs"
/>
{{ change[1].connection.target?.name }}
<span :class="$style.nodeName">{{
change[1].connection.target?.name
}}</span>
</ElDropdownItem>
</ul>
</div>
@@ -588,32 +592,7 @@ const modifiers = [
</template>
<style module lang="scss">
/* Light theme diff colors */
:root,
[data-theme='light'] {
--diff-new: #0eab54;
--diff-new-light: #b4efc4;
--diff-new-faint: #ddfbe7;
--diff-modified: #bf941f;
--diff-modified-light: #f3dca1;
--diff-modified-faint: #fbf1d4;
--diff-del: #f51f32;
--diff-del-light: #fad3d0;
--diff-del-faint: #ffedec;
}
/* Dark theme diff colors */
[data-theme='dark'] {
--diff-new: #38cb7a;
--diff-new-light: #43674f;
--diff-new-faint: #3a463e;
--diff-modified: #d6a625;
--diff-modified-light: #6a5c38;
--diff-modified-faint: #464236;
--diff-del: #fb887a;
--diff-del-light: #7a524e;
--diff-del-faint: #4d3e3d;
}
/* Diff colors are now centralized in @n8n/design-system tokens */
.workflowDiffModal {
margin-bottom: 0;
@@ -690,12 +669,21 @@ const modifiers = [
border-radius: 4px;
padding: var(--spacing-xs) var(--spacing-2xs);
line-height: unset;
min-width: 0;
}
.clickableChangeActive {
background-color: var(--color-background-medium);
}
.nodeName {
flex: 1;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
min-width: 0;
}
.separator {
width: 1px;
height: 10px;