mirror of
https://github.com/Abdulazizzn/n8n-enterprise-unlocked.git
synced 2025-12-20 11:22:15 +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,
|
codex = undefined,
|
||||||
properties = [],
|
properties = [],
|
||||||
group,
|
group,
|
||||||
|
hidden,
|
||||||
|
description,
|
||||||
}: {
|
}: {
|
||||||
name?: INodeTypeDescription['name'];
|
name?: INodeTypeDescription['name'];
|
||||||
icon?: INodeTypeDescription['icon'];
|
icon?: INodeTypeDescription['icon'];
|
||||||
@@ -72,12 +74,14 @@ export const mockNodeTypeDescription = ({
|
|||||||
codex?: INodeTypeDescription['codex'];
|
codex?: INodeTypeDescription['codex'];
|
||||||
properties?: INodeTypeDescription['properties'];
|
properties?: INodeTypeDescription['properties'];
|
||||||
group?: INodeTypeDescription['group'];
|
group?: INodeTypeDescription['group'];
|
||||||
|
hidden?: INodeTypeDescription['hidden'];
|
||||||
|
description?: INodeTypeDescription['description'];
|
||||||
} = {}) =>
|
} = {}) =>
|
||||||
mock<INodeTypeDescription>({
|
mock<INodeTypeDescription>({
|
||||||
name,
|
name,
|
||||||
icon,
|
icon,
|
||||||
displayName: name,
|
displayName: name,
|
||||||
description: '',
|
description: description ?? '',
|
||||||
version,
|
version,
|
||||||
defaults: {
|
defaults: {
|
||||||
name,
|
name,
|
||||||
@@ -93,6 +97,7 @@ export const mockNodeTypeDescription = ({
|
|||||||
documentationUrl: 'https://docs',
|
documentationUrl: 'https://docs',
|
||||||
iconUrl: 'nodes/test-node/icon.svg',
|
iconUrl: 'nodes/test-node/icon.svg',
|
||||||
webhooks: undefined,
|
webhooks: undefined,
|
||||||
|
hidden,
|
||||||
});
|
});
|
||||||
|
|
||||||
export const mockLoadedNodeType = (name: string) =>
|
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 { useTemplatesStore } from '@/stores/templates.store';
|
||||||
import type { BaseTextKey } from '@/plugins/i18n';
|
import type { BaseTextKey } from '@/plugins/i18n';
|
||||||
import { camelCase } from 'lodash-es';
|
import { camelCase } from 'lodash-es';
|
||||||
|
import { useSettingsStore } from '@/stores/settings.store';
|
||||||
|
|
||||||
export interface NodeViewItemSection {
|
export interface NodeViewItemSection {
|
||||||
key: string;
|
key: string;
|
||||||
@@ -149,8 +150,9 @@ export function AIView(_nodes: SimplifiedNodeType[]): NodeView {
|
|||||||
const websiteCategoryURL =
|
const websiteCategoryURL =
|
||||||
templatesStore.constructTemplateRepositoryURL(websiteCategoryURLParams);
|
templatesStore.constructTemplateRepositoryURL(websiteCategoryURLParams);
|
||||||
|
|
||||||
|
const askAiEnabled = useSettingsStore().isAskAiEnabled;
|
||||||
const aiTransformNode = nodeTypesStore.getNodeType(AI_TRANSFORM_NODE_TYPE);
|
const aiTransformNode = nodeTypesStore.getNodeType(AI_TRANSFORM_NODE_TYPE);
|
||||||
const transformNode = aiTransformNode ? [getNodeView(aiTransformNode)] : [];
|
const transformNode = askAiEnabled && aiTransformNode ? [getNodeView(aiTransformNode)] : [];
|
||||||
|
|
||||||
return {
|
return {
|
||||||
value: AI_NODE_CREATOR_VIEW,
|
value: AI_NODE_CREATOR_VIEW,
|
||||||
|
|||||||
@@ -1281,7 +1281,7 @@
|
|||||||
"nodeCreator.aiPanel.aiNodes": "AI Nodes",
|
"nodeCreator.aiPanel.aiNodes": "AI Nodes",
|
||||||
"nodeCreator.aiPanel.aiOtherNodes": "Other AI Nodes",
|
"nodeCreator.aiPanel.aiOtherNodes": "Other AI Nodes",
|
||||||
"nodeCreator.aiPanel.aiOtherNodesDescription": "Embeddings, Vector Stores, LLMs and 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.nodesForAi": "Build autonomous agents, summarize or search documents, etc.",
|
||||||
"nodeCreator.aiPanel.newTag": "New",
|
"nodeCreator.aiPanel.newTag": "New",
|
||||||
"nodeCreator.aiPanel.langchainAiNodes": "AI",
|
"nodeCreator.aiPanel.langchainAiNodes": "AI",
|
||||||
|
|||||||
Reference in New Issue
Block a user