diff --git a/packages/frontend/@n8n/i18n/src/locales/en.json b/packages/frontend/@n8n/i18n/src/locales/en.json index a6d6d67257b..1ccb0cedb68 100644 --- a/packages/frontend/@n8n/i18n/src/locales/en.json +++ b/packages/frontend/@n8n/i18n/src/locales/en.json @@ -3382,5 +3382,15 @@ "whatsNew.versionsBehind": "{count} version behind | {count} versions behind", "whatsNew.update": "Update", "whatsNew.updateAvailable": "You're currently on version {currentVersion}. Update to {latestVersion} to get {count} versions worth of new features, improvements, and fixes. See what changed", - "whatsNew.updateAvailable.changelogLink": "in the full changelog" + "whatsNew.updateAvailable.changelogLink": "in the full changelog", + "workflowDiff.changes": "Changes", + "workflowDiff.nodes": "Nodes", + "workflowDiff.connectors": "Connectors", + "workflowDiff.settings": "Settings", + "workflowDiff.local": "Local", + "workflowDiff.remote": "Remote ({branchName})", + "workflowDiff.noChanges": "No changes", + "workflowDiff.deletedWorkflow": "Deleted workflow", + "workflowDiff.deletedWorkflow.database": "The workflow was deleted on the database", + "workflowDiff.deletedWorkflow.remote": "The workflow was deleted on remote" } 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 similarity index 78% rename from packages/frontend/editor-ui/src/features/workflow-diff/WorkflowDIffModal.test.ts rename to packages/frontend/editor-ui/src/features/workflow-diff/WorkflowDiffModal.test.ts index c98f810f7c5..fdcc6b981d1 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 @@ -302,4 +302,92 @@ describe('WorkflowDiffModal', () => { expect(pullComponent.container.querySelector('.header')).toBeInTheDocument(); expect(pushComponent.container.querySelector('.header')).toBeInTheDocument(); }); + + it('should show empty state when no changes exist in tabs', async () => { + const { getByText } = renderModal({ + pinia: createTestingPinia(), + props: { + data: { + eventBus, + workflowId: 'test-workflow-id', + direction: 'push', + }, + }, + }); + + // Open changes dropdown + const changesButton = getByText('Changes'); + await userEvent.click(changesButton); + + // Wait for dropdown to open and check tabs + await waitFor(() => { + expect(getByText('Nodes')).toBeInTheDocument(); + }); + + // Click on Nodes tab to make it active + await userEvent.click(getByText('Nodes')); + + // Should show "No changes" when there are no node changes + await waitFor(() => { + expect(getByText('No changes')).toBeInTheDocument(); + }); + }); + + it('should show empty state for connectors tab when no connector changes', async () => { + const { getByText } = renderModal({ + pinia: createTestingPinia(), + props: { + data: { + eventBus, + workflowId: 'test-workflow-id', + direction: 'push', + }, + }, + }); + + // Open changes dropdown + const changesButton = getByText('Changes'); + await userEvent.click(changesButton); + + await waitFor(() => { + expect(getByText('Connectors')).toBeInTheDocument(); + }); + + // Click on Connectors tab + await userEvent.click(getByText('Connectors')); + + // Should show "No changes" when there are no connector changes + await waitFor(() => { + expect(getByText('No changes')).toBeInTheDocument(); + }); + }); + + it('should show empty state for settings tab when no settings changes', async () => { + const { getByText } = renderModal({ + pinia: createTestingPinia(), + props: { + data: { + eventBus, + workflowId: 'test-workflow-id', + direction: 'push', + }, + }, + }); + + // Open changes dropdown + const changesButton = getByText('Changes'); + await userEvent.click(changesButton); + + await waitFor(() => { + expect(getByText('Settings')).toBeInTheDocument(); + }); + + // Click on Settings tab + await userEvent.click(getByText('Settings')); + + // Should show "No changes" when there are no settings changes + await waitFor(() => { + expect(getByText('No changes')).toBeInTheDocument(); + }); + }); }); 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 5d3b2898832..ad13ac8cc5e 100644 --- a/packages/frontend/editor-ui/src/features/workflow-diff/WorkflowDiffModal.vue +++ b/packages/frontend/editor-ui/src/features/workflow-diff/WorkflowDiffModal.vue @@ -187,24 +187,24 @@ const activeTab = ref<'nodes' | 'connectors' | 'settings'>(); const tabs = computed(() => [ { value: 'nodes' as const, - label: 'Nodes', - disabled: nodeChanges.value.length === 0, + label: i18n.baseText('workflowDiff.nodes'), + disabled: false, data: { count: nodeChanges.value.length, }, }, { value: 'connectors' as const, - label: 'Connectors', - disabled: connectionsDiff.value.size === 0, + label: i18n.baseText('workflowDiff.connectors'), + disabled: false, data: { count: connectionsDiff.value.size, }, }, { value: 'settings' as const, - label: 'Settings', - disabled: settingsDiff.value.length === 0, + label: i18n.baseText('workflowDiff.settings'), + disabled: false, data: { count: settingsDiff.value.length, }, @@ -220,8 +220,7 @@ function setActiveTab(active: boolean) { telemetry.track('User clicked workflow diff changes button', { workflow_id: props.data.workflowId, }); - const value = tabs.value.find((tab) => !tab.disabled)?.value ?? 'nodes'; - activeTab.value = value; + activeTab.value = 'nodes'; } function trackTabChange(value: 'nodes' | 'connectors' | 'settings') { @@ -367,7 +366,7 @@ const modifiers = [