mirror of
https://github.com/Abdulazizzn/n8n-enterprise-unlocked.git
synced 2025-12-17 18:12:04 +00:00
feat(editor): Tweak node creator search logic for AI sub-nodes (#10025)
Signed-off-by: Oleg Ivaniv <me@olegivaniv.com>
This commit is contained in:
@@ -84,7 +84,7 @@ export const createVectorStoreNode = (args: VectorStoreNodeConstructorArgs) =>
|
|||||||
codex: {
|
codex: {
|
||||||
categories: ['AI'],
|
categories: ['AI'],
|
||||||
subcategories: {
|
subcategories: {
|
||||||
AI: ['Vector Stores'],
|
AI: ['Vector Stores', 'Root Nodes'],
|
||||||
},
|
},
|
||||||
resources: {
|
resources: {
|
||||||
primaryDocumentation: [
|
primaryDocumentation: [
|
||||||
|
|||||||
@@ -83,16 +83,23 @@ export const useViewStacks = defineStore('nodeCreatorViewStacks', () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (stack.search && searchBaseItems.value) {
|
if (stack.search && searchBaseItems.value) {
|
||||||
const searchBase =
|
let searchBase: INodeCreateElement[] = searchBaseItems.value;
|
||||||
searchBaseItems.value.length > 0
|
|
||||||
? searchBaseItems.value
|
|
||||||
: flattenCreateElements(stack.baselineItems ?? []);
|
|
||||||
|
|
||||||
const canvasHasAINodes = useCanvasStore().aiNodes.length > 0;
|
const canvasHasAINodes = useCanvasStore().aiNodes.length > 0;
|
||||||
const filteredNodes =
|
|
||||||
isAiRootView(stack) || canvasHasAINodes ? searchBase : filterOutAiNodes(searchBase);
|
|
||||||
|
|
||||||
const searchResults = extendItemsWithUUID(searchNodes(stack.search || '', filteredNodes));
|
if (searchBaseItems.value.length === 0) {
|
||||||
|
searchBase = flattenCreateElements(stack.baselineItems ?? []);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
// Filter-out AI sub-nodes if canvas has no AI nodes and the root view is not AI
|
||||||
|
!(isAiRootView(stack) || canvasHasAINodes) ||
|
||||||
|
// or if the source is a plus endpoint or a node connection drop
|
||||||
|
['plus_endpoint', 'node_connection_drop'].includes(nodeCreatorStore.openSource)
|
||||||
|
) {
|
||||||
|
searchBase = filterOutAiNodes(searchBase);
|
||||||
|
}
|
||||||
|
|
||||||
|
const searchResults = extendItemsWithUUID(searchNodes(stack.search || '', searchBase));
|
||||||
|
|
||||||
const groupedNodes = groupIfAiNodes(searchResults, false) ?? searchResults;
|
const groupedNodes = groupIfAiNodes(searchResults, false) ?? searchResults;
|
||||||
// Set the active index to the second item if there's a section
|
// Set the active index to the second item if there's a section
|
||||||
@@ -183,12 +190,26 @@ export const useViewStacks = defineStore('nodeCreatorViewStacks', () => {
|
|||||||
return stack.rootView === AI_NODE_CREATOR_VIEW;
|
return stack.rootView === AI_NODE_CREATOR_VIEW;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function filterAiRootNodes(items: NodeCreateElement[]) {
|
||||||
|
return items.filter((node) => {
|
||||||
|
if (node.type !== 'node') return false;
|
||||||
|
|
||||||
|
return node.properties.codex?.subcategories?.[AI_SUBCATEGORY].includes(
|
||||||
|
AI_CATEGORY_ROOT_NODES,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
function groupIfAiNodes(items: INodeCreateElement[], sortAlphabetically = true) {
|
function groupIfAiNodes(items: INodeCreateElement[], sortAlphabetically = true) {
|
||||||
const aiNodes = items.filter((node): node is NodeCreateElement => isAINode(node));
|
const aiNodes = items.filter((node): node is NodeCreateElement => isAINode(node));
|
||||||
|
const canvasHasAINodes = useCanvasStore().aiNodes.length > 0;
|
||||||
|
|
||||||
if (aiNodes.length > 0) {
|
if (aiNodes.length > 0 && (canvasHasAINodes || isAiRootView(getLastActiveStack()))) {
|
||||||
const sectionsMap = new Map<string, NodeViewItemSection>();
|
const sectionsMap = new Map<string, NodeViewItemSection>();
|
||||||
aiNodes.forEach((node) => {
|
const aiRootNodes = filterAiRootNodes(aiNodes);
|
||||||
|
const aiSubNodes = difference(aiNodes, aiRootNodes);
|
||||||
|
|
||||||
|
aiSubNodes.forEach((node) => {
|
||||||
const section = node.properties.codex?.subcategories?.[AI_SUBCATEGORY]?.[0];
|
const section = node.properties.codex?.subcategories?.[AI_SUBCATEGORY]?.[0];
|
||||||
|
|
||||||
if (section) {
|
if (section) {
|
||||||
@@ -209,34 +230,14 @@ export const useViewStacks = defineStore('nodeCreatorViewStacks', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const nonAiNodes = difference(items, aiNodes);
|
const nonAiNodes = difference(items, aiNodes);
|
||||||
const nonAiTriggerNodes = nonAiNodes.filter(
|
|
||||||
(item) => item.type === 'node' && useNodeTypesStore().isTriggerNode(item.properties.name),
|
|
||||||
);
|
|
||||||
|
|
||||||
const nonAiRegularNodes = difference(nonAiNodes, nonAiTriggerNodes);
|
|
||||||
|
|
||||||
if (nonAiNodes.length > 0) {
|
|
||||||
let sectionKey = '';
|
|
||||||
if (nonAiRegularNodes.length && nonAiTriggerNodes.length) {
|
|
||||||
sectionKey = i18n.baseText('nodeCreator.actionsCategory.regularAndTriggers');
|
|
||||||
} else {
|
|
||||||
sectionKey = nonAiRegularNodes.length
|
|
||||||
? i18n.baseText('nodeCreator.actionsCategory.regularNodes')
|
|
||||||
: i18n.baseText('nodeCreator.actionsCategory.triggerNodes');
|
|
||||||
}
|
|
||||||
|
|
||||||
const nodesKeys = nonAiNodes.map((node) => node.key);
|
|
||||||
|
|
||||||
sectionsMap.set(sectionKey, {
|
|
||||||
key: sectionKey,
|
|
||||||
title: sectionKey,
|
|
||||||
items: [...nodesKeys],
|
|
||||||
});
|
|
||||||
}
|
|
||||||
// Convert sectionsMap to array of sections
|
// Convert sectionsMap to array of sections
|
||||||
const sections = Array.from(sectionsMap.values());
|
const sections = Array.from(sectionsMap.values());
|
||||||
|
|
||||||
return groupItemsInSections(items, sections, sortAlphabetically);
|
return [
|
||||||
|
...nonAiNodes,
|
||||||
|
...aiRootNodes,
|
||||||
|
...groupItemsInSections(aiSubNodes, sections, sortAlphabetically),
|
||||||
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
return items;
|
return items;
|
||||||
|
|||||||
@@ -2622,7 +2622,7 @@ export default defineComponent({
|
|||||||
|
|
||||||
// Automatically deselect all nodes and select the current one and also active
|
// Automatically deselect all nodes and select the current one and also active
|
||||||
// current node. But only if it's added manually by the user (not by undo/redo mechanism)
|
// current node. But only if it's added manually by the user (not by undo/redo mechanism)
|
||||||
if (trackHistory) {
|
if (trackHistory && !isAutoAdd) {
|
||||||
this.deselectAllNodes();
|
this.deselectAllNodes();
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
this.nodeSelectedByName(
|
this.nodeSelectedByName(
|
||||||
|
|||||||
Reference in New Issue
Block a user