mirror of
https://github.com/Abdulazizzn/n8n-enterprise-unlocked.git
synced 2025-12-18 02:21:13 +00:00
refactor(editor): Move editor-ui and design-system to frontend dir (no-changelog) (#13564)
This commit is contained in:
@@ -0,0 +1,138 @@
|
||||
import type { ComputedRef, MaybeRef } from 'vue';
|
||||
import { ref, computed, unref } from 'vue';
|
||||
import {
|
||||
CHAIN_SUMMARIZATION_LANGCHAIN_NODE_TYPE,
|
||||
NodeConnectionType,
|
||||
NodeHelpers,
|
||||
} from 'n8n-workflow';
|
||||
import type { INodeTypeDescription, Workflow, INode, INodeParameters } from 'n8n-workflow';
|
||||
import {
|
||||
AI_CATEGORY_AGENTS,
|
||||
AI_CATEGORY_CHAINS,
|
||||
AI_CODE_NODE_TYPE,
|
||||
AI_SUBCATEGORY,
|
||||
CHAT_TRIGGER_NODE_TYPE,
|
||||
MANUAL_CHAT_TRIGGER_NODE_TYPE,
|
||||
} from '@/constants';
|
||||
import type { INodeUi } from '@/Interface';
|
||||
|
||||
export interface ChatTriggerDependencies {
|
||||
getNodeByName: (name: string) => INodeUi | null;
|
||||
getNodeType: (type: string, version: number) => INodeTypeDescription | null;
|
||||
canvasNodes: MaybeRef<INodeUi[]>;
|
||||
workflow: ComputedRef<Workflow>;
|
||||
}
|
||||
|
||||
export function useChatTrigger({
|
||||
getNodeByName,
|
||||
getNodeType,
|
||||
canvasNodes,
|
||||
workflow,
|
||||
}: ChatTriggerDependencies) {
|
||||
const chatTriggerName = ref<string | null>(null);
|
||||
const connectedNode = ref<INode | null>(null);
|
||||
|
||||
const chatTriggerNode = computed(() =>
|
||||
chatTriggerName.value ? getNodeByName(chatTriggerName.value) : null,
|
||||
);
|
||||
|
||||
const allowFileUploads = computed(() => {
|
||||
return (
|
||||
(chatTriggerNode.value?.parameters?.options as INodeParameters)?.allowFileUploads === true
|
||||
);
|
||||
});
|
||||
|
||||
const allowedFilesMimeTypes = computed(() => {
|
||||
return (
|
||||
(
|
||||
chatTriggerNode.value?.parameters?.options as INodeParameters
|
||||
)?.allowedFilesMimeTypes?.toString() ?? ''
|
||||
);
|
||||
});
|
||||
|
||||
/** Gets the chat trigger node from the workflow */
|
||||
function setChatTriggerNode() {
|
||||
const triggerNode = unref(canvasNodes).find((node) =>
|
||||
[CHAT_TRIGGER_NODE_TYPE, MANUAL_CHAT_TRIGGER_NODE_TYPE].includes(node.type),
|
||||
);
|
||||
|
||||
if (!triggerNode) {
|
||||
return;
|
||||
}
|
||||
chatTriggerName.value = triggerNode.name;
|
||||
}
|
||||
|
||||
/** Sets the connected node after finding the trigger */
|
||||
function setConnectedNode() {
|
||||
const triggerNode = chatTriggerNode.value;
|
||||
|
||||
if (!triggerNode) {
|
||||
return;
|
||||
}
|
||||
|
||||
const chatChildren = workflow.value.getChildNodes(triggerNode.name);
|
||||
|
||||
const chatRootNode = chatChildren
|
||||
.reverse()
|
||||
.map((nodeName: string) => getNodeByName(nodeName))
|
||||
.filter((n): n is INodeUi => n !== null)
|
||||
// Reverse the nodes to match the last node logs first
|
||||
.reverse()
|
||||
.find((storeNode: INodeUi): boolean => {
|
||||
// Skip summarization nodes
|
||||
if (storeNode.type === CHAIN_SUMMARIZATION_LANGCHAIN_NODE_TYPE) return false;
|
||||
const nodeType = getNodeType(storeNode.type, storeNode.typeVersion);
|
||||
|
||||
if (!nodeType) return false;
|
||||
|
||||
// Check if node is an AI agent or chain based on its metadata
|
||||
const isAgent =
|
||||
nodeType.codex?.subcategories?.[AI_SUBCATEGORY]?.includes(AI_CATEGORY_AGENTS);
|
||||
const isChain =
|
||||
nodeType.codex?.subcategories?.[AI_SUBCATEGORY]?.includes(AI_CATEGORY_CHAINS);
|
||||
|
||||
// Handle custom AI Langchain Code nodes that could act as chains or agents
|
||||
let isCustomChainOrAgent = false;
|
||||
if (nodeType.name === AI_CODE_NODE_TYPE) {
|
||||
// Get node connection types for inputs and outputs
|
||||
const inputs = NodeHelpers.getNodeInputs(workflow.value, storeNode, nodeType);
|
||||
const inputTypes = NodeHelpers.getConnectionTypes(inputs);
|
||||
|
||||
const outputs = NodeHelpers.getNodeOutputs(workflow.value, storeNode, nodeType);
|
||||
const outputTypes = NodeHelpers.getConnectionTypes(outputs);
|
||||
|
||||
// Validate if node has required AI connection types
|
||||
if (
|
||||
inputTypes.includes(NodeConnectionType.AiLanguageModel) &&
|
||||
inputTypes.includes(NodeConnectionType.Main) &&
|
||||
outputTypes.includes(NodeConnectionType.Main)
|
||||
) {
|
||||
isCustomChainOrAgent = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Skip if node is not an AI component
|
||||
if (!isAgent && !isChain && !isCustomChainOrAgent) return false;
|
||||
|
||||
// Check if this node is connected to the trigger node
|
||||
const parentNodes = workflow.value.getParentNodes(storeNode.name);
|
||||
const isChatChild = parentNodes.some(
|
||||
(parentNodeName) => parentNodeName === triggerNode.name,
|
||||
);
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
|
||||
const result = Boolean(isChatChild && (isAgent || isChain || isCustomChainOrAgent));
|
||||
return result;
|
||||
});
|
||||
connectedNode.value = chatRootNode ?? null;
|
||||
}
|
||||
|
||||
return {
|
||||
allowFileUploads,
|
||||
allowedFilesMimeTypes,
|
||||
chatTriggerNode,
|
||||
connectedNode: computed(() => connectedNode.value),
|
||||
setChatTriggerNode,
|
||||
setConnectedNode,
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user