diff --git a/packages/frontend/@n8n/i18n/src/locales/en.json b/packages/frontend/@n8n/i18n/src/locales/en.json
index d881140cae..193dc126a5 100644
--- a/packages/frontend/@n8n/i18n/src/locales/en.json
+++ b/packages/frontend/@n8n/i18n/src/locales/en.json
@@ -3438,6 +3438,7 @@
"workflowDiff.changes": "Changes",
"workflowDiff.nodes": "Nodes",
"workflowDiff.connectors": "Connectors",
+ "workflowDiff.compare": "Compare versions",
"workflowDiff.settings": "Settings",
"workflowDiff.local": "Local",
"workflowDiff.remote": "Remote ({branchName})",
diff --git a/packages/frontend/editor-ui/src/components/SourceControlPullModal.ee.vue b/packages/frontend/editor-ui/src/components/SourceControlPullModal.ee.vue
index d65c4be058..e3fb94fe96 100644
--- a/packages/frontend/editor-ui/src/components/SourceControlPullModal.ee.vue
+++ b/packages/frontend/editor-ui/src/components/SourceControlPullModal.ee.vue
@@ -15,7 +15,15 @@ import {
notifyUserAboutPullWorkFolderOutcome,
} from '@/utils/sourceControlUtils';
import { type SourceControlledFile, SOURCE_CONTROL_FILE_TYPE } from '@n8n/api-types';
-import { N8nBadge, N8nButton, N8nHeading, N8nInfoTip, N8nLink, N8nText } from '@n8n/design-system';
+import {
+ N8nBadge,
+ N8nButton,
+ N8nHeading,
+ N8nInfoTip,
+ N8nLink,
+ N8nText,
+ N8nTooltip,
+} from '@n8n/design-system';
import { useI18n } from '@n8n/i18n';
import type { EventBus } from '@n8n/utils/event-bus';
import dateformat from 'dateformat';
@@ -355,12 +363,17 @@ onMounted(() => {
{{ getStatusText(file.status) }}
-
+ :content="i18n.baseText('workflowDiff.compare')"
+ placement="top"
+ >
+
+
diff --git a/packages/frontend/editor-ui/src/components/SourceControlPushModal.ee.vue b/packages/frontend/editor-ui/src/components/SourceControlPushModal.ee.vue
index d2d89ab0de..33c8bd54a6 100644
--- a/packages/frontend/editor-ui/src/components/SourceControlPushModal.ee.vue
+++ b/packages/frontend/editor-ui/src/components/SourceControlPushModal.ee.vue
@@ -33,6 +33,7 @@ import {
N8nPopover,
N8nSelect,
N8nText,
+ N8nTooltip,
} from '@n8n/design-system';
import { useI18n } from '@n8n/i18n';
import type { EventBus } from '@n8n/utils/event-bus';
@@ -889,12 +890,17 @@ onMounted(async () => {
{{ getStatusText(file.status) }}
-
+ :content="i18n.baseText('workflowDiff.compare')"
+ placement="top"
+ >
+
+
diff --git a/packages/frontend/editor-ui/src/features/workflow-diff/NodeDiff.vue b/packages/frontend/editor-ui/src/features/workflow-diff/NodeDiff.vue
index 10cf510f94..1aaaf88795 100644
--- a/packages/frontend/editor-ui/src/features/workflow-diff/NodeDiff.vue
+++ b/packages/frontend/editor-ui/src/features/workflow-diff/NodeDiff.vue
@@ -40,6 +40,10 @@ const props = withDefaults(
border: none;
border-radius: 0;
+ :global(.blob-num) {
+ display: none;
+ }
+
&:global([theme='dark']) {
--fgColor-default: var(--color-text-dark);
--bgColor-default: var(--color-background-light);
diff --git a/packages/frontend/editor-ui/src/features/workflow-diff/WorkflowDiffModal.test.ts b/packages/frontend/editor-ui/src/features/workflow-diff/WorkflowDiffModal.test.ts
index 81958e8815..7e741ebd27 100644
--- a/packages/frontend/editor-ui/src/features/workflow-diff/WorkflowDiffModal.test.ts
+++ b/packages/frontend/editor-ui/src/features/workflow-diff/WorkflowDiffModal.test.ts
@@ -133,7 +133,7 @@ describe('WorkflowDiffModal', () => {
// Component should render with the basic structure
expect(container.querySelector('.header')).toBeInTheDocument();
- expect(container.querySelector('h1')).toBeInTheDocument();
+ expect(container.querySelector('h4')).toBeInTheDocument();
});
it('should initialize with correct props', () => {
diff --git a/packages/frontend/editor-ui/src/features/workflow-diff/WorkflowDiffModal.vue b/packages/frontend/editor-ui/src/features/workflow-diff/WorkflowDiffModal.vue
index 167eaabe2c..cc58dc4f88 100644
--- a/packages/frontend/editor-ui/src/features/workflow-diff/WorkflowDiffModal.vue
+++ b/packages/frontend/editor-ui/src/features/workflow-diff/WorkflowDiffModal.vue
@@ -267,9 +267,16 @@ const nodeDiffs = computed(() => {
const targetNode = targetWorkFlow.value?.state.value?.workflow?.nodes.find(
(node) => node.id === selectedDetailId.value,
);
+ function replacer(key: string, value: unknown) {
+ if (key === 'position') {
+ return undefined; // exclude this property
+ }
+ return value;
+ }
+
return {
- oldString: JSON.stringify(sourceNode, null, 2) ?? '',
- newString: JSON.stringify(targetNode, null, 2) ?? '',
+ oldString: JSON.stringify(sourceNode, replacer, 2) ?? '',
+ newString: JSON.stringify(targetNode, replacer, 2) ?? '',
};
});
@@ -399,7 +406,7 @@ const modifiers = [
icon-size="large"
@click="handleBeforeClose"
>
-
+
{{
sourceWorkFlow.state.value?.workflow?.name ||
targetWorkFlow.state.value?.workflow?.name