mirror of
https://github.com/Abdulazizzn/n8n-enterprise-unlocked.git
synced 2025-12-16 09:36:44 +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 { useNDVStore } from '@/stores/ndv.store';
|
||||
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 { useViewStacks } from '@/components/Node/NodeCreator/composables/useViewStacks';
|
||||
|
||||
@@ -64,6 +64,12 @@ vi.mock('@n8n/rest-api-client/api/users', () => ({
|
||||
updateCurrentUserSettings: vi.fn(),
|
||||
}));
|
||||
|
||||
vi.mock('@/stores/projects.store', () => ({
|
||||
useProjectsStore: () => ({
|
||||
currentProjectId: 'test-project-id',
|
||||
}),
|
||||
}));
|
||||
|
||||
let ndvStore: ReturnType<typeof mockedStore<typeof useNDVStore>>;
|
||||
let nodeCreatorStore: ReturnType<typeof mockedStore<typeof useNodeCreatorStore>>;
|
||||
let viewStacks: ReturnType<typeof mockedStore<typeof useViewStacks>>;
|
||||
@@ -134,6 +140,57 @@ describe('useCalloutHelpers()', () => {
|
||||
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))(
|
||||
'opens pre-built agent template %s from NDV successfully',
|
||||
(templateId) => {
|
||||
|
||||
@@ -29,6 +29,7 @@ import {
|
||||
} from '@/utils/templates/workflowSamples';
|
||||
import type { INodeCreateElement, OpenTemplateElement } from '@/Interface';
|
||||
import { useUIStore } from '@/stores/ui.store';
|
||||
import { useProjectsStore } from '@/stores/projects.store';
|
||||
|
||||
export function useCalloutHelpers() {
|
||||
const route = useRoute();
|
||||
@@ -45,6 +46,7 @@ export function useCalloutHelpers() {
|
||||
const viewStacks = useViewStacks();
|
||||
const nodeTypesStore = useNodeTypesStore();
|
||||
const uiStore = useUIStore();
|
||||
const projectsStore = useProjectsStore();
|
||||
|
||||
const isRagStarterCalloutVisible = computed(() => {
|
||||
const template = getRagStarterWorkflowJson();
|
||||
@@ -200,7 +202,11 @@ export function useCalloutHelpers() {
|
||||
const { href } = router.resolve({
|
||||
name: VIEWS.TEMPLATE_IMPORT,
|
||||
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');
|
||||
|
||||
@@ -491,7 +491,7 @@ async function fetchAndSetParentFolder(folderId?: string) {
|
||||
}
|
||||
|
||||
async function fetchAndSetProject(projectId: string) {
|
||||
if (!projectsStore.currentProject) {
|
||||
if (projectsStore.currentProject?.id !== projectId) {
|
||||
const project = await projectsStore.fetchProject(projectId);
|
||||
projectsStore.setCurrentProject(project);
|
||||
}
|
||||
@@ -614,9 +614,15 @@ async function openTemplateFromWorkflowJSON(workflow: WorkflowDataWithTemplateId
|
||||
isBlankRedirect.value = true;
|
||||
const templateId = workflow.meta.templateId;
|
||||
const parentFolderId = route.query.parentFolderId as string | undefined;
|
||||
|
||||
if (projectsStore.currentProjectId) {
|
||||
await fetchAndSetProject(projectsStore.currentProjectId);
|
||||
}
|
||||
await fetchAndSetParentFolder(parentFolderId);
|
||||
|
||||
await router.replace({
|
||||
name: VIEWS.NEW_WORKFLOW,
|
||||
query: { templateId, parentFolderId },
|
||||
query: { templateId, parentFolderId, projectId: projectsStore.currentProjectId },
|
||||
});
|
||||
|
||||
await importTemplate({
|
||||
|
||||
Reference in New Issue
Block a user