feat(editor): Add initial code for NodeView and Canvas rewrite (no-changelog) (#9135)

Co-authored-by: Csaba Tuncsik <csaba.tuncsik@gmail.com>
This commit is contained in:
Alex Grozav
2024-05-23 11:42:10 +03:00
committed by GitHub
parent 8566301731
commit 70948ec71b
49 changed files with 4208 additions and 21 deletions

View File

@@ -0,0 +1,87 @@
import { CanvasNodeKey } from '@/constants';
import { ref } from 'vue';
import type { CanvasElement, CanvasElementData } from '@/types';
export function createCanvasNodeData({
id = 'node',
type = 'test',
typeVersion = 1,
inputs = [],
outputs = [],
renderType = 'default',
}: Partial<CanvasElementData> = {}): CanvasElementData {
return {
id,
type,
typeVersion,
inputs,
outputs,
renderType,
};
}
export function createCanvasNodeElement({
id = '1',
type = 'node',
label = 'Node',
position = { x: 100, y: 100 },
data,
}: Partial<
Omit<CanvasElement, 'data'> & { data: Partial<CanvasElementData> }
> = {}): CanvasElement {
return {
id,
type,
label,
position,
data: createCanvasNodeData({ id, type, ...data }),
};
}
export function createCanvasNodeProps({
id = 'node',
label = 'Test Node',
selected = false,
data = {},
} = {}) {
return {
id,
label,
selected,
data: createCanvasNodeData(data),
};
}
export function createCanvasNodeProvide({
id = 'node',
label = 'Test Node',
selected = false,
data = {},
} = {}) {
const props = createCanvasNodeProps({ id, label, selected, data });
return {
[`${CanvasNodeKey}`]: {
id: ref(props.id),
label: ref(props.label),
selected: ref(props.selected),
data: ref(props.data),
},
};
}
export function createCanvasConnection(
nodeA: CanvasElement,
nodeB: CanvasElement,
{ sourceIndex = 0, targetIndex = 0 } = {},
) {
const nodeAOutput = nodeA.data?.outputs[sourceIndex];
const nodeBInput = nodeA.data?.inputs[targetIndex];
return {
id: `${nodeA.id}-${nodeB.id}`,
source: nodeA.id,
target: nodeB.id,
...(nodeAOutput ? { sourceHandle: `outputs/${nodeAOutput.type}/${nodeAOutput.index}` } : {}),
...(nodeBInput ? { targetHandle: `inputs/${nodeBInput.type}/${nodeBInput.index}` } : {}),
};
}

View File

@@ -0,0 +1 @@
export * from './canvas';

View File

@@ -1,5 +1,10 @@
import type { INodeTypeData, INodeTypeDescription, IN8nUISettings } from 'n8n-workflow';
import { AGENT_NODE_TYPE, CHAT_TRIGGER_NODE_TYPE, MANUAL_TRIGGER_NODE_TYPE } from '@/constants';
import {
AGENT_NODE_TYPE,
SET_NODE_TYPE,
CHAT_TRIGGER_NODE_TYPE,
MANUAL_TRIGGER_NODE_TYPE,
} from '@/constants';
import nodeTypesJson from '../../../nodes-base/dist/types/nodes.json';
import aiNodeTypesJson from '../../../@n8n/nodes-langchain/dist/types/nodes.json';
@@ -16,6 +21,12 @@ export const testingNodeTypes: INodeTypeData = {
description: findNodeWithName(MANUAL_TRIGGER_NODE_TYPE),
},
},
[SET_NODE_TYPE]: {
sourcePath: '',
type: {
description: findNodeWithName(SET_NODE_TYPE),
},
},
[CHAT_TRIGGER_NODE_TYPE]: {
sourcePath: '',
type: {
@@ -32,6 +43,7 @@ export const testingNodeTypes: INodeTypeData = {
export const defaultMockNodeTypes: INodeTypeData = {
[MANUAL_TRIGGER_NODE_TYPE]: testingNodeTypes[MANUAL_TRIGGER_NODE_TYPE],
[SET_NODE_TYPE]: testingNodeTypes[SET_NODE_TYPE],
};
export function mockNodeTypesToArray(nodeTypes: INodeTypeData): INodeTypeDescription[] {

View File

@@ -17,22 +17,21 @@ import type { ProjectSharingData } from '@/features/projects/projects.types';
import type { RouteLocationNormalized } from 'vue-router';
export function createTestNodeTypes(data: INodeTypeData = {}): INodeTypes {
const getResolvedKey = (key: string) => {
const resolvedKeyParts = key.split(/[\/.]/);
return resolvedKeyParts[resolvedKeyParts.length - 1];
};
const nodeTypes = {
...defaultMockNodeTypes,
...Object.keys(data).reduce<INodeTypeData>((acc, key) => {
acc[getResolvedKey(key)] = data[key];
acc[key] = data[key];
return acc;
}, {}),
};
function getKnownTypes(): IDataObject {
return {};
}
function getByName(nodeType: string): INodeType | IVersionedNodeType {
return nodeTypes[getResolvedKey(nodeType)].type;
return nodeTypes[nodeType].type;
}
function getByNameAndVersion(nodeType: string, version?: number): INodeType {
@@ -40,6 +39,7 @@ export function createTestNodeTypes(data: INodeTypeData = {}): INodeTypes {
}
return {
getKnownTypes,
getByName,
getByNameAndVersion,
};

View File

@@ -19,7 +19,8 @@ export type RenderOptions = Parameters<typeof render>[1] & {
const TelemetryPlugin: Plugin<{}> = {
install(app) {
app.config.globalProperties.$telemetry = {
track(event: string, properties?: object) {},
// eslint-disable-next-line @typescript-eslint/no-unused-vars
track(..._: unknown[]) {},
} as Telemetry;
},
};

View File

@@ -32,6 +32,7 @@ export const retry = async (
export const waitAllPromises = async () => await new Promise((resolve) => setTimeout(resolve));
export const SETTINGS_STORE_DEFAULT_STATE: ISettingsState = {
initialized: true,
settings: defaultSettings,
promptsData: {
message: '',
@@ -62,14 +63,13 @@ export const SETTINGS_STORE_DEFAULT_STATE: ISettingsState = {
loginLabel: '',
loginEnabled: false,
},
mfa: {
enabled: false,
},
onboardingCallPromptEnabled: false,
saveDataErrorExecution: 'all',
saveDataSuccessExecution: 'all',
saveManualExecutions: false,
initialized: false,
mfa: {
enabled: false,
},
};
export const getDropdownItems = async (dropdownTriggerParent: HTMLElement) => {