mirror of
https://github.com/Abdulazizzn/n8n-enterprise-unlocked.git
synced 2025-12-17 01:56:46 +00:00
feat(editor): Node Creator AI nodes improvements (#9484)
Signed-off-by: Oleg Ivaniv <me@olegivaniv.com>
This commit is contained in:
@@ -6,12 +6,18 @@ import type {
|
||||
INodeCreateElement,
|
||||
SectionCreateElement,
|
||||
} from '@/Interface';
|
||||
import { AI_SUBCATEGORY, CORE_NODES_CATEGORY, DEFAULT_SUBCATEGORY } from '@/constants';
|
||||
import {
|
||||
AI_CATEGORY_AGENTS,
|
||||
AI_SUBCATEGORY,
|
||||
CORE_NODES_CATEGORY,
|
||||
DEFAULT_SUBCATEGORY,
|
||||
} from '@/constants';
|
||||
import { v4 as uuidv4 } from 'uuid';
|
||||
|
||||
import { sublimeSearch } from '@/utils/sortUtils';
|
||||
import { i18n } from '@/plugins/i18n';
|
||||
import type { NodeViewItemSection } from './viewsData';
|
||||
import { i18n } from '@/plugins/i18n';
|
||||
import { sortBy } from 'lodash-es';
|
||||
|
||||
export function transformNodeType(
|
||||
node: SimplifiedNodeType,
|
||||
@@ -70,6 +76,7 @@ export function sortNodeCreateElements(nodes: INodeCreateElement[]) {
|
||||
export function searchNodes(searchFilter: string, items: INodeCreateElement[]) {
|
||||
// In order to support the old search we need to remove the 'trigger' part
|
||||
const trimmedFilter = searchFilter.toLowerCase().replace('trigger', '').trimEnd();
|
||||
|
||||
const result = (
|
||||
sublimeSearch<INodeCreateElement>(trimmedFilter, items, [
|
||||
{ key: 'properties.displayName', weight: 1.3 },
|
||||
@@ -83,38 +90,72 @@ export function searchNodes(searchFilter: string, items: INodeCreateElement[]) {
|
||||
export function flattenCreateElements(items: INodeCreateElement[]): INodeCreateElement[] {
|
||||
return items.map((item) => (item.type === 'section' ? item.children : item)).flat();
|
||||
}
|
||||
export function isAINode(node: INodeCreateElement) {
|
||||
const isNode = node.type === 'node';
|
||||
if (!isNode) return false;
|
||||
|
||||
if (node.properties.codex?.categories?.includes(AI_SUBCATEGORY)) {
|
||||
const isAgentSubcategory =
|
||||
node.properties.codex?.subcategories?.[AI_SUBCATEGORY]?.includes(AI_CATEGORY_AGENTS);
|
||||
|
||||
return !isAgentSubcategory;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
export function groupItemsInSections(
|
||||
items: INodeCreateElement[],
|
||||
sections: string[] | NodeViewItemSection[],
|
||||
sortAlphabetically = true,
|
||||
): INodeCreateElement[] {
|
||||
const filteredSections = sections.filter(
|
||||
(section): section is NodeViewItemSection => typeof section === 'object',
|
||||
);
|
||||
|
||||
const itemsBySection = items.reduce((acc: Record<string, INodeCreateElement[]>, item) => {
|
||||
const section = filteredSections.find((s) => s.items.includes(item.key));
|
||||
const key = section?.key ?? 'other';
|
||||
acc[key] = [...(acc[key] ?? []), item];
|
||||
return acc;
|
||||
}, {});
|
||||
const itemsBySection = (items2: INodeCreateElement[]) =>
|
||||
items2.reduce((acc: Record<string, INodeCreateElement[]>, item) => {
|
||||
const section = filteredSections.find((s) => s.items.includes(item.key));
|
||||
|
||||
const result: SectionCreateElement[] = filteredSections
|
||||
.map(
|
||||
const key = section?.key ?? 'other';
|
||||
if (key) {
|
||||
acc[key] = [...(acc[key] ?? []), item];
|
||||
}
|
||||
return acc;
|
||||
}, {});
|
||||
|
||||
const mapNewSections = (
|
||||
newSections: NodeViewItemSection[],
|
||||
children: Record<string, INodeCreateElement[]>,
|
||||
) =>
|
||||
newSections.map(
|
||||
(section): SectionCreateElement => ({
|
||||
type: 'section',
|
||||
key: section.key,
|
||||
title: section.title,
|
||||
children: sortNodeCreateElements(itemsBySection[section.key] ?? []),
|
||||
children: sortAlphabetically
|
||||
? sortNodeCreateElements(children[section.key] ?? [])
|
||||
: children[section.key] ?? [],
|
||||
}),
|
||||
)
|
||||
);
|
||||
|
||||
const nonAINodes = items.filter((item) => !isAINode(item));
|
||||
const AINodes = items.filter((item) => isAINode(item));
|
||||
|
||||
const nonAINodesBySection = itemsBySection(nonAINodes);
|
||||
const nonAINodesSections = mapNewSections(filteredSections, nonAINodesBySection);
|
||||
|
||||
const AINodesBySection = itemsBySection(AINodes);
|
||||
|
||||
const AINodesSections = mapNewSections(sortBy(filteredSections, ['title']), AINodesBySection);
|
||||
|
||||
const result = [...nonAINodesSections, ...AINodesSections]
|
||||
.concat({
|
||||
type: 'section',
|
||||
key: 'other',
|
||||
title: i18n.baseText('nodeCreator.sectionNames.other'),
|
||||
children: sortNodeCreateElements(itemsBySection.other ?? []),
|
||||
children: sortNodeCreateElements(nonAINodesBySection.other ?? []),
|
||||
})
|
||||
.filter((section) => section.children.length > 0);
|
||||
.filter((section) => section.type !== 'section' || section.children.length > 0);
|
||||
|
||||
if (result.length <= 1) {
|
||||
return items;
|
||||
|
||||
Reference in New Issue
Block a user