diff --git a/packages/frontend/editor-ui/src/experiments/instanceAiWorkflowPreviewSuggestions/components/WorkflowPreviewSuggestions.test.ts b/packages/frontend/editor-ui/src/experiments/instanceAiWorkflowPreviewSuggestions/components/WorkflowPreviewSuggestions.test.ts index 50a031aef06..f1bf3287107 100644 --- a/packages/frontend/editor-ui/src/experiments/instanceAiWorkflowPreviewSuggestions/components/WorkflowPreviewSuggestions.test.ts +++ b/packages/frontend/editor-ui/src/experiments/instanceAiWorkflowPreviewSuggestions/components/WorkflowPreviewSuggestions.test.ts @@ -10,6 +10,11 @@ vi.mock('@/app/composables/useTelemetry', () => ({ useTelemetry: () => ({ track: telemetryTrack }), })); +const websiteTemplateRepositoryURL = 'https://n8n.io/workflows?utm_instance=test'; +vi.mock('@/features/workflows/templates/templates.store', () => ({ + useTemplatesStore: () => ({ websiteTemplateRepositoryURL }), +})); + const renderComponent = createComponentRenderer(WorkflowPreviewSuggestions, { props: { suggestions, @@ -48,4 +53,11 @@ describe('WorkflowPreviewSuggestions', () => { suggestion_id: suggestion.id, }); }); + + it('links "see all" to the templates website URL with instance parameters', () => { + const { container } = renderComponent(); + + const link = container.querySelector('a'); + expect(link).toHaveAttribute('href', websiteTemplateRepositoryURL); + }); }); diff --git a/packages/frontend/editor-ui/src/experiments/instanceAiWorkflowPreviewSuggestions/components/WorkflowPreviewSuggestions.vue b/packages/frontend/editor-ui/src/experiments/instanceAiWorkflowPreviewSuggestions/components/WorkflowPreviewSuggestions.vue index 70df2fb9146..469014dc9e1 100644 --- a/packages/frontend/editor-ui/src/experiments/instanceAiWorkflowPreviewSuggestions/components/WorkflowPreviewSuggestions.vue +++ b/packages/frontend/editor-ui/src/experiments/instanceAiWorkflowPreviewSuggestions/components/WorkflowPreviewSuggestions.vue @@ -3,6 +3,7 @@ import { N8nIcon } from '@n8n/design-system'; import { useI18n, type BaseTextKey } from '@n8n/i18n'; import { onUnmounted, ref } from 'vue'; import { useTelemetry } from '@/app/composables/useTelemetry'; +import { useTemplatesStore } from '@/features/workflows/templates/templates.store'; import { type WorkflowPreviewSuggestion } from '../suggestions'; const PREVIEW_HOVER_DELAY_MS = 30; @@ -27,6 +28,7 @@ const emit = defineEmits<{ const i18n = useI18n(); const telemetry = useTelemetry(); +const templatesStore = useTemplatesStore(); const activePreview = ref(null); let hoverTimer: ReturnType | null = null; const hoverStartTimes = new Map(); @@ -123,7 +125,7 @@ onUnmounted(clearPreview); {{ i18n.baseText(suggestion.labelKey) }} ({ + usePersonalizedTemplatesV2Store: () => ({ + nodes: ['n8n-nodes-base.slack'], + getNodeData: () => ({ youtube: [], starter: [], popular: [] }), + getTemplateData: vi.fn(), + trackModalTabView: vi.fn(), + trackSeeMoreClick: vi.fn(), + }), +})); + +vi.mock('@/app/stores/nodeTypes.store', () => ({ + useNodeTypesStore: () => ({ + getNodeType: (name: string) => ({ name, displayName: 'Slack' }), + }), +})); + +vi.mock('@/features/workflows/templates/templates.store', () => ({ + useTemplatesStore: () => ({ + websiteTemplateRepositoryParameters: new URLSearchParams({ + utm_source: 'n8n_app', + utm_instance: 'https://test.instance/', + }), + constructTemplateRepositoryURL: (params: URLSearchParams) => + `https://n8n.io/workflows/?${params.toString()}`, + }), +})); + +const renderComponent = createComponentRenderer(NodeRecommendationModal, { + props: { + modalName: EXPERIMENT_TEMPLATE_RECO_V2_KEY, + data: {}, + }, + global: { + stubs: { + NodeIcon: true, + }, + }, +}); + +describe('NodeRecommendationModal', () => { + beforeEach(() => { + const modalsContainer = document.createElement('div'); + modalsContainer.id = APP_MODALS_ELEMENT_ID; + document.body.appendChild(modalsContainer); + }); + + afterEach(() => { + document.getElementById(APP_MODALS_ELEMENT_ID)?.remove(); + }); + + it('builds "see more" links from the template repository parameters', async () => { + const { findByText } = renderComponent({ + pinia: createTestingPinia({ + initialState: { + [STORES.UI]: { + modalsById: { + [EXPERIMENT_TEMPLATE_RECO_V2_KEY]: { open: true }, + }, + }, + }, + }), + }); + + const starterLink = (await findByText('See more starter templates')).closest('a'); + expect(starterLink).toHaveAttribute( + 'href', + 'https://n8n.io/workflows/?utm_source=n8n_app&utm_instance=https%3A%2F%2Ftest.instance%2F&integrations=Slack&q=Simple', + ); + + const popularLink = (await findByText('See more popular templates')).closest('a'); + expect(popularLink).toHaveAttribute( + 'href', + 'https://n8n.io/workflows/?utm_source=n8n_app&utm_instance=https%3A%2F%2Ftest.instance%2F&integrations=Slack', + ); + }); +}); diff --git a/packages/frontend/editor-ui/src/experiments/templateRecoV2/components/NodeRecommendationModal.vue b/packages/frontend/editor-ui/src/experiments/templateRecoV2/components/NodeRecommendationModal.vue index 74792d144cf..cbe0b94984b 100644 --- a/packages/frontend/editor-ui/src/experiments/templateRecoV2/components/NodeRecommendationModal.vue +++ b/packages/frontend/editor-ui/src/experiments/templateRecoV2/components/NodeRecommendationModal.vue @@ -1,8 +1,9 @@