mirror of
https://github.com/Abdulazizzn/n8n-enterprise-unlocked.git
synced 2025-12-17 01:56:46 +00:00
fix(editor): Respect project id and parent folder for callouts (no-changelog) (#19318)
This commit is contained in:
@@ -4,7 +4,7 @@ import { createTestingPinia } from '@pinia/testing';
|
|||||||
import { PrebuiltAgentTemplates, SampleTemplates } from '@/utils/templates/workflowSamples';
|
import { PrebuiltAgentTemplates, SampleTemplates } from '@/utils/templates/workflowSamples';
|
||||||
import { useNDVStore } from '@/stores/ndv.store';
|
import { useNDVStore } from '@/stores/ndv.store';
|
||||||
import { mockedStore } from '@/__tests__/utils';
|
import { mockedStore } from '@/__tests__/utils';
|
||||||
import { NODE_CREATOR_OPEN_SOURCES } from '@/constants';
|
import { NODE_CREATOR_OPEN_SOURCES, VIEWS } from '@/constants';
|
||||||
import { useNodeCreatorStore } from '@/stores/nodeCreator.store';
|
import { useNodeCreatorStore } from '@/stores/nodeCreator.store';
|
||||||
import { useViewStacks } from '@/components/Node/NodeCreator/composables/useViewStacks';
|
import { useViewStacks } from '@/components/Node/NodeCreator/composables/useViewStacks';
|
||||||
|
|
||||||
@@ -64,6 +64,12 @@ vi.mock('@n8n/rest-api-client/api/users', () => ({
|
|||||||
updateCurrentUserSettings: vi.fn(),
|
updateCurrentUserSettings: vi.fn(),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
vi.mock('@/stores/projects.store', () => ({
|
||||||
|
useProjectsStore: () => ({
|
||||||
|
currentProjectId: 'test-project-id',
|
||||||
|
}),
|
||||||
|
}));
|
||||||
|
|
||||||
let ndvStore: ReturnType<typeof mockedStore<typeof useNDVStore>>;
|
let ndvStore: ReturnType<typeof mockedStore<typeof useNDVStore>>;
|
||||||
let nodeCreatorStore: ReturnType<typeof mockedStore<typeof useNodeCreatorStore>>;
|
let nodeCreatorStore: ReturnType<typeof mockedStore<typeof useNodeCreatorStore>>;
|
||||||
let viewStacks: ReturnType<typeof mockedStore<typeof useViewStacks>>;
|
let viewStacks: ReturnType<typeof mockedStore<typeof useViewStacks>>;
|
||||||
@@ -134,6 +140,57 @@ describe('useCalloutHelpers()', () => {
|
|||||||
expect(mocks.track).not.toHaveBeenCalled();
|
expect(mocks.track).not.toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('includes project ID in template URL when opening template', () => {
|
||||||
|
vi.spyOn(window, 'open').mockImplementation(() => null);
|
||||||
|
mocks.resolve.mockReturnValue({ href: 'n8n.io/template/test' });
|
||||||
|
|
||||||
|
const { openSampleWorkflowTemplate } = useCalloutHelpers();
|
||||||
|
|
||||||
|
openSampleWorkflowTemplate(SampleTemplates.RagStarterTemplate, {
|
||||||
|
telemetry: {
|
||||||
|
source: 'ndv',
|
||||||
|
nodeType: 'testNode',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(mocks.resolve).toHaveBeenCalledWith({
|
||||||
|
name: VIEWS.TEMPLATE_IMPORT,
|
||||||
|
params: { id: SampleTemplates.RagStarterTemplate },
|
||||||
|
query: {
|
||||||
|
fromJson: 'true',
|
||||||
|
projectId: 'test-project-id',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('includes folder ID in template URL when opening template', () => {
|
||||||
|
vi.spyOn(window, 'open').mockImplementation(() => null);
|
||||||
|
mocks.resolve.mockReturnValue({ href: 'n8n.io/template/test' });
|
||||||
|
mocks.useRoute.mockReturnValueOnce({
|
||||||
|
query: {},
|
||||||
|
params: { folderId: 'my-folder-id' },
|
||||||
|
});
|
||||||
|
|
||||||
|
const { openSampleWorkflowTemplate } = useCalloutHelpers();
|
||||||
|
|
||||||
|
openSampleWorkflowTemplate(SampleTemplates.EasyAiTemplate, {
|
||||||
|
telemetry: {
|
||||||
|
source: 'ndv',
|
||||||
|
nodeType: 'testNode',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(mocks.resolve).toHaveBeenCalledWith({
|
||||||
|
name: VIEWS.TEMPLATE_IMPORT,
|
||||||
|
params: { id: SampleTemplates.EasyAiTemplate },
|
||||||
|
query: {
|
||||||
|
fromJson: 'true',
|
||||||
|
projectId: 'test-project-id',
|
||||||
|
parentFolderId: 'my-folder-id',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
it.each(Object.values(PrebuiltAgentTemplates))(
|
it.each(Object.values(PrebuiltAgentTemplates))(
|
||||||
'opens pre-built agent template %s from NDV successfully',
|
'opens pre-built agent template %s from NDV successfully',
|
||||||
(templateId) => {
|
(templateId) => {
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ import {
|
|||||||
} from '@/utils/templates/workflowSamples';
|
} from '@/utils/templates/workflowSamples';
|
||||||
import type { INodeCreateElement, OpenTemplateElement } from '@/Interface';
|
import type { INodeCreateElement, OpenTemplateElement } from '@/Interface';
|
||||||
import { useUIStore } from '@/stores/ui.store';
|
import { useUIStore } from '@/stores/ui.store';
|
||||||
|
import { useProjectsStore } from '@/stores/projects.store';
|
||||||
|
|
||||||
export function useCalloutHelpers() {
|
export function useCalloutHelpers() {
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
@@ -45,6 +46,7 @@ export function useCalloutHelpers() {
|
|||||||
const viewStacks = useViewStacks();
|
const viewStacks = useViewStacks();
|
||||||
const nodeTypesStore = useNodeTypesStore();
|
const nodeTypesStore = useNodeTypesStore();
|
||||||
const uiStore = useUIStore();
|
const uiStore = useUIStore();
|
||||||
|
const projectsStore = useProjectsStore();
|
||||||
|
|
||||||
const isRagStarterCalloutVisible = computed(() => {
|
const isRagStarterCalloutVisible = computed(() => {
|
||||||
const template = getRagStarterWorkflowJson();
|
const template = getRagStarterWorkflowJson();
|
||||||
@@ -200,7 +202,11 @@ export function useCalloutHelpers() {
|
|||||||
const { href } = router.resolve({
|
const { href } = router.resolve({
|
||||||
name: VIEWS.TEMPLATE_IMPORT,
|
name: VIEWS.TEMPLATE_IMPORT,
|
||||||
params: { id: template.meta.templateId },
|
params: { id: template.meta.templateId },
|
||||||
query: { fromJson: 'true', parentFolderId: route.params.folderId },
|
query: {
|
||||||
|
fromJson: 'true',
|
||||||
|
parentFolderId: route.params.folderId,
|
||||||
|
projectId: projectsStore.currentProjectId,
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
window.open(href, '_blank');
|
window.open(href, '_blank');
|
||||||
|
|||||||
@@ -491,7 +491,7 @@ async function fetchAndSetParentFolder(folderId?: string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function fetchAndSetProject(projectId: string) {
|
async function fetchAndSetProject(projectId: string) {
|
||||||
if (!projectsStore.currentProject) {
|
if (projectsStore.currentProject?.id !== projectId) {
|
||||||
const project = await projectsStore.fetchProject(projectId);
|
const project = await projectsStore.fetchProject(projectId);
|
||||||
projectsStore.setCurrentProject(project);
|
projectsStore.setCurrentProject(project);
|
||||||
}
|
}
|
||||||
@@ -614,9 +614,15 @@ async function openTemplateFromWorkflowJSON(workflow: WorkflowDataWithTemplateId
|
|||||||
isBlankRedirect.value = true;
|
isBlankRedirect.value = true;
|
||||||
const templateId = workflow.meta.templateId;
|
const templateId = workflow.meta.templateId;
|
||||||
const parentFolderId = route.query.parentFolderId as string | undefined;
|
const parentFolderId = route.query.parentFolderId as string | undefined;
|
||||||
|
|
||||||
|
if (projectsStore.currentProjectId) {
|
||||||
|
await fetchAndSetProject(projectsStore.currentProjectId);
|
||||||
|
}
|
||||||
|
await fetchAndSetParentFolder(parentFolderId);
|
||||||
|
|
||||||
await router.replace({
|
await router.replace({
|
||||||
name: VIEWS.NEW_WORKFLOW,
|
name: VIEWS.NEW_WORKFLOW,
|
||||||
query: { templateId, parentFolderId },
|
query: { templateId, parentFolderId, projectId: projectsStore.currentProjectId },
|
||||||
});
|
});
|
||||||
|
|
||||||
await importTemplate({
|
await importTemplate({
|
||||||
|
|||||||
Reference in New Issue
Block a user