Files
n8n-enterprise-unlocked/packages/editor-ui/src/components/Node/NodeCreator/viewsData.ts
2024-06-06 13:34:30 +02:00

531 lines
14 KiB
TypeScript

import {
CORE_NODES_CATEGORY,
WEBHOOK_NODE_TYPE,
OTHER_TRIGGER_NODES_SUBCATEGORY,
EXECUTE_WORKFLOW_TRIGGER_NODE_TYPE,
FORM_TRIGGER_NODE_TYPE,
MANUAL_TRIGGER_NODE_TYPE,
MANUAL_CHAT_TRIGGER_NODE_TYPE,
SCHEDULE_TRIGGER_NODE_TYPE,
REGULAR_NODE_CREATOR_VIEW,
TRANSFORM_DATA_SUBCATEGORY,
FLOWS_CONTROL_SUBCATEGORY,
TRIGGER_NODE_CREATOR_VIEW,
EMAIL_IMAP_NODE_TYPE,
DEFAULT_SUBCATEGORY,
AI_NODE_CREATOR_VIEW,
AI_CATEGORY_AGENTS,
AI_CATEGORY_CHAINS,
AI_CATEGORY_DOCUMENT_LOADERS,
AI_CATEGORY_LANGUAGE_MODELS,
AI_CATEGORY_MEMORY,
AI_CATEGORY_OUTPUTPARSER,
AI_CATEGORY_RETRIEVERS,
AI_CATEGORY_TEXT_SPLITTERS,
AI_CATEGORY_TOOLS,
AI_CATEGORY_VECTOR_STORES,
AI_SUBCATEGORY,
AI_CATEGORY_EMBEDDING,
AI_OTHERS_NODE_CREATOR_VIEW,
AI_UNCATEGORIZED_CATEGORY,
CONVERT_TO_FILE_NODE_TYPE,
EXTRACT_FROM_FILE_NODE_TYPE,
SET_NODE_TYPE,
CODE_NODE_TYPE,
DATETIME_NODE_TYPE,
FILTER_NODE_TYPE,
REMOVE_DUPLICATES_NODE_TYPE,
SPLIT_OUT_NODE_TYPE,
LIMIT_NODE_TYPE,
SUMMARIZE_NODE_TYPE,
AGGREGATE_NODE_TYPE,
MERGE_NODE_TYPE,
HTML_NODE_TYPE,
MARKDOWN_NODE_TYPE,
XML_NODE_TYPE,
CRYPTO_NODE_TYPE,
IF_NODE_TYPE,
SPLIT_IN_BATCHES_NODE_TYPE,
HTTP_REQUEST_NODE_TYPE,
HELPERS_SUBCATEGORY,
RSS_READ_NODE_TYPE,
EMAIL_SEND_NODE_TYPE,
EDIT_IMAGE_NODE_TYPE,
COMPRESSION_NODE_TYPE,
AI_CODE_TOOL_LANGCHAIN_NODE_TYPE,
AI_WORKFLOW_TOOL_LANGCHAIN_NODE_TYPE,
} from '@/constants';
import { useI18n } from '@/composables/useI18n';
import { useNodeTypesStore } from '@/stores/nodeTypes.store';
import type { SimplifiedNodeType } from '@/Interface';
import type { INodeTypeDescription } from 'n8n-workflow';
import { NodeConnectionType } from 'n8n-workflow';
import { useTemplatesStore } from '@/stores/templates.store';
export interface NodeViewItemSection {
key: string;
title: string;
items: string[];
}
export interface NodeViewItem {
key: string;
type: string;
properties: {
name?: string;
title?: string;
icon?: string;
iconProps?: {
color?: string;
};
url?: string;
connectionType?: NodeConnectionType;
panelClass?: string;
group?: string[];
sections?: NodeViewItemSection[];
description?: string;
displayName?: string;
tag?: {
type: string;
text: string;
};
forceIncludeNodes?: string[];
iconData?: {
type: string;
icon?: string;
fileBuffer?: string;
};
};
category?: string | string[];
}
interface NodeView {
value: string;
title: string;
info?: string;
subtitle?: string;
items: NodeViewItem[];
}
function getAiNodesBySubcategory(nodes: INodeTypeDescription[], subcategory: string) {
return nodes
.filter(
(node) => !node.hidden && node.codex?.subcategories?.[AI_SUBCATEGORY]?.includes(subcategory),
)
.map((node) => ({
key: node.name,
type: 'node',
properties: {
group: [],
name: node.name,
displayName: node.displayName,
title: node.displayName,
description: node.description,
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
icon: node.icon!,
iconUrl: node.iconUrl,
},
}))
.sort((a, b) => a.properties.displayName.localeCompare(b.properties.displayName));
}
export function AIView(_nodes: SimplifiedNodeType[]): NodeView {
const i18n = useI18n();
const nodeTypesStore = useNodeTypesStore();
const templatesStore = useTemplatesStore();
const chainNodes = getAiNodesBySubcategory(nodeTypesStore.allLatestNodeTypes, AI_CATEGORY_CHAINS);
const agentNodes = getAiNodesBySubcategory(nodeTypesStore.allLatestNodeTypes, AI_CATEGORY_AGENTS);
return {
value: AI_NODE_CREATOR_VIEW,
title: i18n.baseText('nodeCreator.aiPanel.aiNodes'),
subtitle: i18n.baseText('nodeCreator.aiPanel.selectAiNode'),
items: [
{
key: 'ai_templates_root',
type: 'link',
properties: {
title: i18n.baseText('nodeCreator.aiPanel.linkItem.title'),
icon: 'box-open',
description: i18n.baseText('nodeCreator.aiPanel.linkItem.description'),
name: 'ai_templates_root',
url: templatesStore.getWebsiteCategoryURL(undefined, 'AdvancedAI'),
tag: {
type: 'info',
text: i18n.baseText('nodeCreator.triggerHelperPanel.manualTriggerTag'),
},
},
},
...agentNodes,
...chainNodes,
{
key: AI_OTHERS_NODE_CREATOR_VIEW,
type: 'view',
properties: {
title: i18n.baseText('nodeCreator.aiPanel.aiOtherNodes'),
icon: 'robot',
description: i18n.baseText('nodeCreator.aiPanel.aiOtherNodesDescription'),
},
},
],
};
}
export function AINodesView(_nodes: SimplifiedNodeType[]): NodeView {
const i18n = useI18n();
function getAISubcategoryProperties(nodeConnectionType: NodeConnectionType) {
return {
connectionType: nodeConnectionType,
iconProps: {
color: `var(--node-type-${nodeConnectionType}-color)`,
},
panelClass: `nodes-list-panel-${nodeConnectionType}`,
};
}
return {
value: AI_OTHERS_NODE_CREATOR_VIEW,
title: i18n.baseText('nodeCreator.aiPanel.aiOtherNodes'),
subtitle: i18n.baseText('nodeCreator.aiPanel.selectAiNode'),
items: [
{
key: AI_CATEGORY_DOCUMENT_LOADERS,
type: 'subcategory',
properties: {
title: AI_CATEGORY_DOCUMENT_LOADERS,
icon: 'file-import',
...getAISubcategoryProperties(NodeConnectionType.AiDocument),
},
},
{
key: AI_CATEGORY_LANGUAGE_MODELS,
type: 'subcategory',
properties: {
title: AI_CATEGORY_LANGUAGE_MODELS,
icon: 'language',
...getAISubcategoryProperties(NodeConnectionType.AiLanguageModel),
},
},
{
key: AI_CATEGORY_MEMORY,
type: 'subcategory',
properties: {
title: AI_CATEGORY_MEMORY,
icon: 'brain',
...getAISubcategoryProperties(NodeConnectionType.AiMemory),
},
},
{
key: AI_CATEGORY_OUTPUTPARSER,
type: 'subcategory',
properties: {
title: AI_CATEGORY_OUTPUTPARSER,
icon: 'list',
...getAISubcategoryProperties(NodeConnectionType.AiOutputParser),
},
},
{
key: AI_CATEGORY_RETRIEVERS,
type: 'subcategory',
properties: {
title: AI_CATEGORY_RETRIEVERS,
icon: 'search',
...getAISubcategoryProperties(NodeConnectionType.AiRetriever),
},
},
{
key: AI_CATEGORY_TEXT_SPLITTERS,
type: 'subcategory',
properties: {
title: AI_CATEGORY_TEXT_SPLITTERS,
icon: 'grip-lines-vertical',
...getAISubcategoryProperties(NodeConnectionType.AiTextSplitter),
},
},
{
type: 'subcategory',
key: AI_CATEGORY_TOOLS,
category: CORE_NODES_CATEGORY,
properties: {
title: AI_CATEGORY_TOOLS,
icon: 'tools',
...getAISubcategoryProperties(NodeConnectionType.AiTool),
sections: [
{
key: 'popular',
title: i18n.baseText('nodeCreator.sectionNames.popular'),
items: [AI_WORKFLOW_TOOL_LANGCHAIN_NODE_TYPE, AI_CODE_TOOL_LANGCHAIN_NODE_TYPE],
},
],
},
},
{
key: AI_CATEGORY_EMBEDDING,
type: 'subcategory',
properties: {
title: AI_CATEGORY_EMBEDDING,
icon: 'vector-square',
...getAISubcategoryProperties(NodeConnectionType.AiEmbedding),
},
},
{
key: AI_CATEGORY_VECTOR_STORES,
type: 'subcategory',
properties: {
title: AI_CATEGORY_VECTOR_STORES,
icon: 'project-diagram',
...getAISubcategoryProperties(NodeConnectionType.AiVectorStore),
},
},
{
key: AI_UNCATEGORIZED_CATEGORY,
type: 'subcategory',
properties: {
title: AI_UNCATEGORIZED_CATEGORY,
icon: 'code',
},
},
],
};
}
export function TriggerView() {
const i18n = useI18n();
const view: NodeView = {
value: TRIGGER_NODE_CREATOR_VIEW,
title: i18n.baseText('nodeCreator.triggerHelperPanel.selectATrigger'),
subtitle: i18n.baseText('nodeCreator.triggerHelperPanel.selectATriggerDescription'),
items: [
{
key: MANUAL_TRIGGER_NODE_TYPE,
type: 'node',
category: [CORE_NODES_CATEGORY],
properties: {
group: [],
name: MANUAL_TRIGGER_NODE_TYPE,
displayName: i18n.baseText('nodeCreator.triggerHelperPanel.manualTriggerDisplayName'),
description: i18n.baseText('nodeCreator.triggerHelperPanel.manualTriggerDescription'),
icon: 'fa:mouse-pointer',
},
},
{
key: DEFAULT_SUBCATEGORY,
type: 'subcategory',
properties: {
forceIncludeNodes: [WEBHOOK_NODE_TYPE, EMAIL_IMAP_NODE_TYPE],
title: 'App Trigger Nodes',
icon: 'satellite-dish',
},
},
{
key: SCHEDULE_TRIGGER_NODE_TYPE,
type: 'node',
category: [CORE_NODES_CATEGORY],
properties: {
group: [],
name: SCHEDULE_TRIGGER_NODE_TYPE,
displayName: i18n.baseText('nodeCreator.triggerHelperPanel.scheduleTriggerDisplayName'),
description: i18n.baseText('nodeCreator.triggerHelperPanel.scheduleTriggerDescription'),
icon: 'fa:clock',
},
},
{
key: WEBHOOK_NODE_TYPE,
type: 'node',
category: [CORE_NODES_CATEGORY],
properties: {
group: [],
name: WEBHOOK_NODE_TYPE,
displayName: i18n.baseText('nodeCreator.triggerHelperPanel.webhookTriggerDisplayName'),
description: i18n.baseText('nodeCreator.triggerHelperPanel.webhookTriggerDescription'),
iconData: {
type: 'file',
icon: 'webhook',
fileBuffer: '/static/webhook-icon.svg',
},
},
},
{
key: FORM_TRIGGER_NODE_TYPE,
type: 'node',
category: [CORE_NODES_CATEGORY],
properties: {
group: [],
name: FORM_TRIGGER_NODE_TYPE,
displayName: i18n.baseText('nodeCreator.triggerHelperPanel.formTriggerDisplayName'),
description: i18n.baseText('nodeCreator.triggerHelperPanel.formTriggerDescription'),
iconData: {
type: 'file',
icon: 'form',
fileBuffer: '/static/form-grey.svg',
},
},
},
{
key: EXECUTE_WORKFLOW_TRIGGER_NODE_TYPE,
type: 'node',
category: [CORE_NODES_CATEGORY],
properties: {
group: [],
name: EXECUTE_WORKFLOW_TRIGGER_NODE_TYPE,
displayName: i18n.baseText('nodeCreator.triggerHelperPanel.workflowTriggerDisplayName'),
description: i18n.baseText('nodeCreator.triggerHelperPanel.workflowTriggerDescription'),
icon: 'fa:sign-out-alt',
},
},
{
key: MANUAL_CHAT_TRIGGER_NODE_TYPE,
type: 'node',
category: [CORE_NODES_CATEGORY],
properties: {
group: [],
name: MANUAL_CHAT_TRIGGER_NODE_TYPE,
displayName: i18n.baseText('nodeCreator.triggerHelperPanel.manualChatTriggerDisplayName'),
description: i18n.baseText('nodeCreator.triggerHelperPanel.manualChatTriggerDescription'),
icon: 'fa:comments',
},
},
{
type: 'subcategory',
key: OTHER_TRIGGER_NODES_SUBCATEGORY,
category: CORE_NODES_CATEGORY,
properties: {
title: OTHER_TRIGGER_NODES_SUBCATEGORY,
icon: 'folder-open',
},
},
],
};
return view;
}
export function RegularView(nodes: SimplifiedNodeType[]) {
const i18n = useI18n();
const view: NodeView = {
value: REGULAR_NODE_CREATOR_VIEW,
title: i18n.baseText('nodeCreator.triggerHelperPanel.whatHappensNext'),
items: [
{
key: DEFAULT_SUBCATEGORY,
type: 'subcategory',
properties: {
title: 'App Regular Nodes',
icon: 'globe',
forceIncludeNodes: [RSS_READ_NODE_TYPE, EMAIL_SEND_NODE_TYPE],
},
},
{
type: 'subcategory',
key: TRANSFORM_DATA_SUBCATEGORY,
category: CORE_NODES_CATEGORY,
properties: {
title: TRANSFORM_DATA_SUBCATEGORY,
icon: 'pen',
sections: [
{
key: 'popular',
title: i18n.baseText('nodeCreator.sectionNames.popular'),
items: [SET_NODE_TYPE, CODE_NODE_TYPE, DATETIME_NODE_TYPE],
},
{
key: 'addOrRemove',
title: i18n.baseText('nodeCreator.sectionNames.transform.addOrRemove'),
items: [
FILTER_NODE_TYPE,
REMOVE_DUPLICATES_NODE_TYPE,
SPLIT_OUT_NODE_TYPE,
LIMIT_NODE_TYPE,
],
},
{
key: 'combine',
title: i18n.baseText('nodeCreator.sectionNames.transform.combine'),
items: [SUMMARIZE_NODE_TYPE, AGGREGATE_NODE_TYPE, MERGE_NODE_TYPE],
},
{
key: 'convert',
title: i18n.baseText('nodeCreator.sectionNames.transform.convert'),
items: [
HTML_NODE_TYPE,
MARKDOWN_NODE_TYPE,
XML_NODE_TYPE,
CRYPTO_NODE_TYPE,
EXTRACT_FROM_FILE_NODE_TYPE,
CONVERT_TO_FILE_NODE_TYPE,
COMPRESSION_NODE_TYPE,
EDIT_IMAGE_NODE_TYPE,
],
},
],
},
},
{
type: 'subcategory',
key: FLOWS_CONTROL_SUBCATEGORY,
category: CORE_NODES_CATEGORY,
properties: {
title: FLOWS_CONTROL_SUBCATEGORY,
icon: 'code-branch',
sections: [
{
key: 'popular',
title: i18n.baseText('nodeCreator.sectionNames.popular'),
items: [FILTER_NODE_TYPE, IF_NODE_TYPE, SPLIT_IN_BATCHES_NODE_TYPE, MERGE_NODE_TYPE],
},
],
},
},
{
type: 'subcategory',
key: HELPERS_SUBCATEGORY,
category: CORE_NODES_CATEGORY,
properties: {
title: HELPERS_SUBCATEGORY,
icon: 'toolbox',
sections: [
{
key: 'popular',
title: i18n.baseText('nodeCreator.sectionNames.popular'),
items: [HTTP_REQUEST_NODE_TYPE, WEBHOOK_NODE_TYPE, CODE_NODE_TYPE],
},
],
},
},
],
};
const hasAINodes = (nodes ?? []).some((node) => node.codex?.categories?.includes(AI_SUBCATEGORY));
if (hasAINodes)
view.items.push({
key: AI_NODE_CREATOR_VIEW,
type: 'view',
properties: {
title: i18n.baseText('nodeCreator.aiPanel.langchainAiNodes'),
icon: 'robot',
description: i18n.baseText('nodeCreator.aiPanel.nodesForAi'),
tag: {
type: 'success',
text: i18n.baseText('nodeCreator.aiPanel.newTag'),
},
borderless: true,
},
} as NodeViewItem);
view.items.push({
key: TRIGGER_NODE_CREATOR_VIEW,
type: 'view',
properties: {
title: i18n.baseText('nodeCreator.triggerHelperPanel.addAnotherTrigger'),
icon: 'bolt',
description: i18n.baseText('nodeCreator.triggerHelperPanel.addAnotherTriggerDescription'),
},
});
return view;
}