mirror of
https://github.com/Abdulazizzn/n8n-enterprise-unlocked.git
synced 2025-12-18 02:21:13 +00:00
fix(editor): Show Transform Node in Panel only if available (#14830)
This commit is contained in:
@@ -62,6 +62,8 @@ export const mockNodeTypeDescription = ({
|
||||
codex = undefined,
|
||||
properties = [],
|
||||
group,
|
||||
hidden,
|
||||
description,
|
||||
}: {
|
||||
name?: INodeTypeDescription['name'];
|
||||
icon?: INodeTypeDescription['icon'];
|
||||
@@ -72,12 +74,14 @@ export const mockNodeTypeDescription = ({
|
||||
codex?: INodeTypeDescription['codex'];
|
||||
properties?: INodeTypeDescription['properties'];
|
||||
group?: INodeTypeDescription['group'];
|
||||
hidden?: INodeTypeDescription['hidden'];
|
||||
description?: INodeTypeDescription['description'];
|
||||
} = {}) =>
|
||||
mock<INodeTypeDescription>({
|
||||
name,
|
||||
icon,
|
||||
displayName: name,
|
||||
description: '',
|
||||
description: description ?? '',
|
||||
version,
|
||||
defaults: {
|
||||
name,
|
||||
@@ -93,6 +97,7 @@ export const mockNodeTypeDescription = ({
|
||||
documentationUrl: 'https://docs',
|
||||
iconUrl: 'nodes/test-node/icon.svg',
|
||||
webhooks: undefined,
|
||||
hidden,
|
||||
});
|
||||
|
||||
export const mockLoadedNodeType = (name: string) =>
|
||||
|
||||
@@ -0,0 +1,134 @@
|
||||
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
|
||||
|
||||
exports[`viewsData > AIView > should return ai view with ai transform node 1`] = `
|
||||
{
|
||||
"items": [
|
||||
{
|
||||
"key": "ai_templates_root",
|
||||
"properties": {
|
||||
"description": "See what's possible and get started 5x faster",
|
||||
"icon": "box-open",
|
||||
"name": "ai_templates_root",
|
||||
"tag": {
|
||||
"text": "Recommended",
|
||||
"type": "info",
|
||||
},
|
||||
"title": "AI Templates",
|
||||
"url": "template-repository-url.n8n.io?test=value&utm_user_role=AdvancedAI",
|
||||
},
|
||||
"type": "link",
|
||||
},
|
||||
{
|
||||
"key": "agent",
|
||||
"properties": {
|
||||
"description": "example mock agent node",
|
||||
"displayName": "agent",
|
||||
"group": [],
|
||||
"icon": "fa:pen",
|
||||
"iconUrl": "nodes/test-node/icon.svg",
|
||||
"name": "agent",
|
||||
"title": "agent",
|
||||
},
|
||||
"type": "node",
|
||||
},
|
||||
{
|
||||
"key": "chain",
|
||||
"properties": {
|
||||
"description": "example mock chain node",
|
||||
"displayName": "chain",
|
||||
"group": [],
|
||||
"icon": "fa:pen",
|
||||
"iconUrl": "nodes/test-node/icon.svg",
|
||||
"name": "chain",
|
||||
"title": "chain",
|
||||
},
|
||||
"type": "node",
|
||||
},
|
||||
{
|
||||
"key": "n8n-nodes-base.aiTransform",
|
||||
"properties": {
|
||||
"description": "",
|
||||
"displayName": "n8n-nodes-base.aiTransform",
|
||||
"group": [],
|
||||
"icon": "fa:pen",
|
||||
"iconUrl": "nodes/test-node/icon.svg",
|
||||
"name": "n8n-nodes-base.aiTransform",
|
||||
"title": "n8n-nodes-base.aiTransform",
|
||||
},
|
||||
"type": "node",
|
||||
},
|
||||
{
|
||||
"key": "AI Other",
|
||||
"properties": {
|
||||
"description": "Embeddings, Vector Stores, LLMs and other AI nodes",
|
||||
"icon": "robot",
|
||||
"title": "Other AI Nodes",
|
||||
},
|
||||
"type": "view",
|
||||
},
|
||||
],
|
||||
"subtitle": "Select an AI Node to add to your workflow",
|
||||
"title": "AI Nodes",
|
||||
"value": "AI",
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`viewsData > AIView > should return ai view without ai transform node if ask ai is not enabled 1`] = `
|
||||
{
|
||||
"items": [
|
||||
{
|
||||
"key": "ai_templates_root",
|
||||
"properties": {
|
||||
"description": "See what's possible and get started 5x faster",
|
||||
"icon": "box-open",
|
||||
"name": "ai_templates_root",
|
||||
"tag": {
|
||||
"text": "Recommended",
|
||||
"type": "info",
|
||||
},
|
||||
"title": "AI Templates",
|
||||
"url": "template-repository-url.n8n.io?test=value&utm_user_role=AdvancedAI",
|
||||
},
|
||||
"type": "link",
|
||||
},
|
||||
{
|
||||
"key": "agent",
|
||||
"properties": {
|
||||
"description": "example mock agent node",
|
||||
"displayName": "agent",
|
||||
"group": [],
|
||||
"icon": "fa:pen",
|
||||
"iconUrl": "nodes/test-node/icon.svg",
|
||||
"name": "agent",
|
||||
"title": "agent",
|
||||
},
|
||||
"type": "node",
|
||||
},
|
||||
{
|
||||
"key": "chain",
|
||||
"properties": {
|
||||
"description": "example mock chain node",
|
||||
"displayName": "chain",
|
||||
"group": [],
|
||||
"icon": "fa:pen",
|
||||
"iconUrl": "nodes/test-node/icon.svg",
|
||||
"name": "chain",
|
||||
"title": "chain",
|
||||
},
|
||||
"type": "node",
|
||||
},
|
||||
{
|
||||
"key": "AI Other",
|
||||
"properties": {
|
||||
"description": "Embeddings, Vector Stores, LLMs and other AI nodes",
|
||||
"icon": "robot",
|
||||
"title": "Other AI Nodes",
|
||||
},
|
||||
"type": "view",
|
||||
},
|
||||
],
|
||||
"subtitle": "Select an AI Node to add to your workflow",
|
||||
"title": "AI Nodes",
|
||||
"value": "AI",
|
||||
}
|
||||
`;
|
||||
@@ -0,0 +1,90 @@
|
||||
import { setActivePinia } from 'pinia';
|
||||
import { createTestingPinia } from '@pinia/testing';
|
||||
import { AI_CATEGORY_AGENTS, AI_CATEGORY_CHAINS, AI_TRANSFORM_NODE_TYPE } from '@/constants';
|
||||
import type { INodeTypeDescription } from 'n8n-workflow';
|
||||
import { START_NODE_TYPE } from 'n8n-workflow';
|
||||
import { useSettingsStore } from '@/stores/settings.store';
|
||||
import { AIView } from './viewsData';
|
||||
import { mockNodeTypeDescription } from '@/__tests__/mocks';
|
||||
import { useTemplatesStore } from '@/stores/templates.store';
|
||||
|
||||
const getNodeType = vi.fn();
|
||||
|
||||
const aiTransformNode = mockNodeTypeDescription({ name: AI_TRANSFORM_NODE_TYPE });
|
||||
|
||||
const otherNodes = (
|
||||
[
|
||||
{ name: START_NODE_TYPE },
|
||||
{
|
||||
name: 'agentHidden',
|
||||
description: 'example mock agent node',
|
||||
hidden: true,
|
||||
codex: { subcategories: { AI: [AI_CATEGORY_AGENTS] } },
|
||||
},
|
||||
{
|
||||
name: 'agent',
|
||||
description: 'example mock agent node',
|
||||
codex: { subcategories: { AI: [AI_CATEGORY_AGENTS] } },
|
||||
},
|
||||
{
|
||||
name: 'chainHidden',
|
||||
description: 'example mock chain node',
|
||||
hidden: true,
|
||||
codex: { subcategories: { AI: [AI_CATEGORY_CHAINS] } },
|
||||
},
|
||||
{
|
||||
name: 'chain',
|
||||
description: 'example mock chain node',
|
||||
codex: { subcategories: { AI: [AI_CATEGORY_CHAINS] } },
|
||||
},
|
||||
] as Array<Partial<INodeTypeDescription>>
|
||||
).map(mockNodeTypeDescription);
|
||||
|
||||
vi.mock('@/stores/nodeTypes.store', () => ({
|
||||
useNodeTypesStore: vi.fn(() => ({
|
||||
getNodeType,
|
||||
allLatestNodeTypes: [aiTransformNode, ...otherNodes],
|
||||
})),
|
||||
}));
|
||||
|
||||
describe('viewsData', () => {
|
||||
beforeAll(() => {
|
||||
setActivePinia(createTestingPinia());
|
||||
|
||||
const templatesStore = useTemplatesStore();
|
||||
|
||||
vi.spyOn(templatesStore, 'websiteTemplateRepositoryParameters', 'get').mockImplementation(
|
||||
() => new URLSearchParams({ test: 'value' }),
|
||||
);
|
||||
vi.spyOn(templatesStore, 'constructTemplateRepositoryURL').mockImplementation(
|
||||
(params) => `template-repository-url.n8n.io?${params.toString()}`,
|
||||
);
|
||||
getNodeType.mockImplementation((nodeName: string) => {
|
||||
if (nodeName === AI_TRANSFORM_NODE_TYPE) {
|
||||
return aiTransformNode;
|
||||
}
|
||||
|
||||
return null;
|
||||
});
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
vi.clearAllMocks();
|
||||
});
|
||||
|
||||
describe('AIView', () => {
|
||||
test('should return ai view with ai transform node', () => {
|
||||
const settingsStore = useSettingsStore();
|
||||
vi.spyOn(settingsStore, 'isAskAiEnabled', 'get').mockReturnValue(true);
|
||||
|
||||
expect(AIView([])).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('should return ai view without ai transform node if ask ai is not enabled', () => {
|
||||
const settingsStore = useSettingsStore();
|
||||
vi.spyOn(settingsStore, 'isAskAiEnabled', 'get').mockReturnValue(false);
|
||||
|
||||
expect(AIView([])).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -67,6 +67,7 @@ import type { NodeConnectionType } from 'n8n-workflow';
|
||||
import { useTemplatesStore } from '@/stores/templates.store';
|
||||
import type { BaseTextKey } from '@/plugins/i18n';
|
||||
import { camelCase } from 'lodash-es';
|
||||
import { useSettingsStore } from '@/stores/settings.store';
|
||||
|
||||
export interface NodeViewItemSection {
|
||||
key: string;
|
||||
@@ -149,8 +150,9 @@ export function AIView(_nodes: SimplifiedNodeType[]): NodeView {
|
||||
const websiteCategoryURL =
|
||||
templatesStore.constructTemplateRepositoryURL(websiteCategoryURLParams);
|
||||
|
||||
const askAiEnabled = useSettingsStore().isAskAiEnabled;
|
||||
const aiTransformNode = nodeTypesStore.getNodeType(AI_TRANSFORM_NODE_TYPE);
|
||||
const transformNode = aiTransformNode ? [getNodeView(aiTransformNode)] : [];
|
||||
const transformNode = askAiEnabled && aiTransformNode ? [getNodeView(aiTransformNode)] : [];
|
||||
|
||||
return {
|
||||
value: AI_NODE_CREATOR_VIEW,
|
||||
|
||||
@@ -1281,7 +1281,7 @@
|
||||
"nodeCreator.aiPanel.aiNodes": "AI Nodes",
|
||||
"nodeCreator.aiPanel.aiOtherNodes": "Other AI Nodes",
|
||||
"nodeCreator.aiPanel.aiOtherNodesDescription": "Embeddings, Vector Stores, LLMs and other AI nodes",
|
||||
"nodeCreator.aiPanel.selectAiNode": "Select an Al Node to add to your workflow",
|
||||
"nodeCreator.aiPanel.selectAiNode": "Select an AI Node to add to your workflow",
|
||||
"nodeCreator.aiPanel.nodesForAi": "Build autonomous agents, summarize or search documents, etc.",
|
||||
"nodeCreator.aiPanel.newTag": "New",
|
||||
"nodeCreator.aiPanel.langchainAiNodes": "AI",
|
||||
|
||||
Reference in New Issue
Block a user