mirror of
https://github.com/Abdulazizzn/n8n-enterprise-unlocked.git
synced 2025-12-17 18:12:04 +00:00
feat(editor): Debug executions in the editor (#6834)
This commit is contained in:
@@ -218,6 +218,7 @@ import {
|
||||
useMessage,
|
||||
useToast,
|
||||
useTitleChange,
|
||||
useExecutionDebugging,
|
||||
} from '@/composables';
|
||||
import { useUniqueNodeName } from '@/composables/useUniqueNodeName';
|
||||
import { useI18n } from '@/composables/useI18n';
|
||||
@@ -355,6 +356,7 @@ export default defineComponent({
|
||||
...useToast(),
|
||||
...useMessage(),
|
||||
...useUniqueNodeName(),
|
||||
...useExecutionDebugging(),
|
||||
// eslint-disable-next-line @typescript-eslint/no-misused-promises
|
||||
...workflowRun.setup?.(props),
|
||||
};
|
||||
@@ -365,7 +367,7 @@ export default defineComponent({
|
||||
},
|
||||
watch: {
|
||||
// Listen to route changes and load the workflow accordingly
|
||||
$route(to: Route, from: Route) {
|
||||
async $route(to: Route, from: Route) {
|
||||
this.readOnlyEnvRouteCheck();
|
||||
|
||||
const currentTab = getNodeViewTab(to);
|
||||
@@ -388,14 +390,13 @@ export default defineComponent({
|
||||
this.resetWorkspace();
|
||||
this.uiStore.stateIsDirty = previousDirtyState;
|
||||
}
|
||||
void this.loadCredentials();
|
||||
void this.initView().then(() => {
|
||||
this.stopLoading();
|
||||
if (this.blankRedirect) {
|
||||
this.blankRedirect = false;
|
||||
}
|
||||
});
|
||||
await Promise.all([this.loadCredentials(), this.initView()]);
|
||||
this.stopLoading();
|
||||
if (this.blankRedirect) {
|
||||
this.blankRedirect = false;
|
||||
}
|
||||
}
|
||||
await this.checkAndInitDebugMode();
|
||||
}
|
||||
// Also, when landing on executions tab, check if workflow data is changed
|
||||
if (currentTab === MAIN_HEADER_TABS.EXECUTIONS) {
|
||||
@@ -561,7 +562,7 @@ export default defineComponent({
|
||||
workflowClasses() {
|
||||
const returnClasses = [];
|
||||
if (this.ctrlKeyPressed || this.moveCanvasKeyPressed) {
|
||||
if (this.uiStore.nodeViewMoveInProgress === true) {
|
||||
if (this.uiStore.nodeViewMoveInProgress) {
|
||||
returnClasses.push('move-in-process');
|
||||
} else {
|
||||
returnClasses.push('move-active');
|
||||
@@ -1084,7 +1085,7 @@ export default defineComponent({
|
||||
lastSelectedNode.name,
|
||||
);
|
||||
}
|
||||
} else if (e.key === 'a' && this.isCtrlKeyPressed(e) === true) {
|
||||
} else if (e.key === 'a' && this.isCtrlKeyPressed(e)) {
|
||||
// Select all nodes
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
@@ -1504,7 +1505,7 @@ export default defineComponent({
|
||||
const currentTab = getNodeViewTab(this.$route);
|
||||
if (currentTab === MAIN_HEADER_TABS.WORKFLOW) {
|
||||
let workflowData: IWorkflowDataUpdate | undefined;
|
||||
if (this.editAllowedCheck() === false) {
|
||||
if (!this.editAllowedCheck()) {
|
||||
return;
|
||||
}
|
||||
// Check if it is an URL which could contain workflow data
|
||||
@@ -1779,11 +1780,9 @@ export default defineComponent({
|
||||
parameters: {},
|
||||
};
|
||||
|
||||
const credentialPerType =
|
||||
nodeTypeData.credentials &&
|
||||
nodeTypeData.credentials
|
||||
.map((type) => this.credentialsStore.getUsableCredentialByType(type.name))
|
||||
.flat();
|
||||
const credentialPerType = nodeTypeData.credentials
|
||||
?.map((type) => this.credentialsStore.getUsableCredentialByType(type.name))
|
||||
.flat();
|
||||
|
||||
if (credentialPerType && credentialPerType.length === 1) {
|
||||
const defaultCredential = credentialPerType[0];
|
||||
@@ -1820,10 +1819,7 @@ export default defineComponent({
|
||||
return newNodeData;
|
||||
}
|
||||
|
||||
if (
|
||||
Object.keys(authDisplayOptions).length === 1 &&
|
||||
authDisplayOptions['authentication']
|
||||
) {
|
||||
if (Object.keys(authDisplayOptions).length === 1 && authDisplayOptions.authentication) {
|
||||
// ignore complex case when there's multiple dependencies
|
||||
newNodeData.credentials = credentials;
|
||||
|
||||
@@ -1957,7 +1953,7 @@ export default defineComponent({
|
||||
|
||||
newNodeData.name = this.uniqueNodeName(localizedName);
|
||||
|
||||
if (nodeTypeData.webhooks && nodeTypeData.webhooks.length) {
|
||||
if (nodeTypeData.webhooks?.length) {
|
||||
newNodeData.webhookId = uuid();
|
||||
}
|
||||
|
||||
@@ -2007,9 +2003,8 @@ export default defineComponent({
|
||||
targetNodeName: string,
|
||||
targetNodeOuputIndex: number,
|
||||
): IConnection | undefined {
|
||||
const nodeConnections = (
|
||||
this.workflowsStore.outgoingConnectionsByNodeName(sourceNodeName) as INodeConnections
|
||||
).main;
|
||||
const nodeConnections =
|
||||
this.workflowsStore.outgoingConnectionsByNodeName(sourceNodeName).main;
|
||||
if (nodeConnections) {
|
||||
const connections: IConnection[] | null = nodeConnections[sourceNodeOutputIndex];
|
||||
|
||||
@@ -2091,7 +2086,7 @@ export default defineComponent({
|
||||
if (lastSelectedNode) {
|
||||
await this.$nextTick();
|
||||
|
||||
if (lastSelectedConnection && lastSelectedConnection.__meta) {
|
||||
if (lastSelectedConnection?.__meta) {
|
||||
this.__deleteJSPlumbConnection(lastSelectedConnection, trackHistory);
|
||||
|
||||
const targetNodeName = lastSelectedConnection.__meta.targetNodeName;
|
||||
@@ -2432,8 +2427,8 @@ export default defineComponent({
|
||||
const { top, left, right, bottom } = element.getBoundingClientRect();
|
||||
const [x, y] = NodeViewUtils.getMousePosition(e);
|
||||
if (top <= y && bottom >= y && left - inputMargin <= x && right >= x) {
|
||||
const nodeName = (element as HTMLElement).dataset['name'] as string;
|
||||
const node = this.workflowsStore.getNodeByName(nodeName) as INodeUi | null;
|
||||
const nodeName = (element as HTMLElement).dataset.name as string;
|
||||
const node = this.workflowsStore.getNodeByName(nodeName);
|
||||
if (node) {
|
||||
const nodeType = this.nodeTypesStore.getNodeType(node.type, node.typeVersion);
|
||||
if (nodeType && nodeType.inputs && nodeType.inputs.length === 1) {
|
||||
@@ -2482,7 +2477,7 @@ export default defineComponent({
|
||||
.forEach((endpoint) => setTimeout(() => endpoint.instance.revalidate(endpoint.element), 0));
|
||||
},
|
||||
onPlusEndpointClick(endpoint: Endpoint) {
|
||||
if (endpoint && endpoint.__meta) {
|
||||
if (endpoint?.__meta) {
|
||||
this.insertNodeAfterSelected({
|
||||
sourceId: endpoint.__meta.nodeId,
|
||||
index: endpoint.__meta.index,
|
||||
@@ -2576,7 +2571,6 @@ export default defineComponent({
|
||||
this.stopLoading();
|
||||
},
|
||||
async tryToAddWelcomeSticky(): Promise<void> {
|
||||
const newWorkflow = this.workflowData;
|
||||
this.canvasStore.zoomToFit();
|
||||
},
|
||||
async initView(): Promise<void> {
|
||||
@@ -2633,8 +2627,8 @@ export default defineComponent({
|
||||
|
||||
if (workflow) {
|
||||
this.titleSet(workflow.name, 'IDLE');
|
||||
// Open existing workflow
|
||||
await this.openWorkflow(workflow);
|
||||
await this.checkAndInitDebugMode();
|
||||
}
|
||||
} else if (this.$route.meta?.nodeView === true) {
|
||||
// Create new workflow
|
||||
@@ -2758,8 +2752,7 @@ export default defineComponent({
|
||||
const nodeTypeData = this.nodeTypesStore.getNodeType(node.type, node.typeVersion);
|
||||
|
||||
if (
|
||||
nodeTypeData &&
|
||||
nodeTypeData.maxNodes !== undefined &&
|
||||
nodeTypeData?.maxNodes !== undefined &&
|
||||
this.getNodeTypeCount(node.type) >= nodeTypeData.maxNodes
|
||||
) {
|
||||
this.showMaxNodeTypeError(nodeTypeData);
|
||||
@@ -2914,7 +2907,7 @@ export default defineComponent({
|
||||
}) {
|
||||
const pinData = this.workflowsStore.getPinData;
|
||||
|
||||
if (pinData && pinData[name]) return;
|
||||
if (pinData?.[name]) return;
|
||||
|
||||
const sourceNodeName = name;
|
||||
const sourceNode = this.workflowsStore.getNodeByName(sourceNodeName);
|
||||
@@ -2959,7 +2952,7 @@ export default defineComponent({
|
||||
|
||||
if (output.isArtificialRecoveredEventItem) {
|
||||
NodeViewUtils.recoveredConnection(connection);
|
||||
} else if ((!output || !output.total) && !output.isArtificialRecoveredEventItem) {
|
||||
} else if (!output?.total && !output.isArtificialRecoveredEventItem) {
|
||||
NodeViewUtils.resetConnection(connection);
|
||||
} else {
|
||||
NodeViewUtils.addConnectionOutputSuccess(connection, output);
|
||||
@@ -2971,7 +2964,7 @@ export default defineComponent({
|
||||
sourceNodeName,
|
||||
parseInt(sourceOutputIndex, 10),
|
||||
);
|
||||
if (endpoint && endpoint.endpoint) {
|
||||
if (endpoint?.endpoint) {
|
||||
const output = outputMap[sourceOutputIndex][NODE_OUTPUT_DEFAULT_KEY][0];
|
||||
|
||||
if (output && output.total > 0) {
|
||||
@@ -3261,7 +3254,7 @@ export default defineComponent({
|
||||
);
|
||||
},
|
||||
async addNodes(nodes: INodeUi[], connections?: IConnections, trackHistory = false) {
|
||||
if (!nodes || !nodes.length) {
|
||||
if (!nodes?.length) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -3751,7 +3744,7 @@ export default defineComponent({
|
||||
const mode =
|
||||
this.nodeCreatorStore.selectedView === TRIGGER_NODE_CREATOR_VIEW ? 'trigger' : 'regular';
|
||||
|
||||
if (createNodeActive === true) this.nodeCreatorStore.setOpenSource(source);
|
||||
if (createNodeActive) this.nodeCreatorStore.setOpenSource(source);
|
||||
void this.$externalHooks().run('nodeView.createNodeActiveChanged', {
|
||||
source,
|
||||
mode,
|
||||
@@ -3872,6 +3865,15 @@ export default defineComponent({
|
||||
});
|
||||
}
|
||||
},
|
||||
async checkAndInitDebugMode() {
|
||||
if (this.$route.name === VIEWS.EXECUTION_DEBUG) {
|
||||
this.titleSet(this.workflowName, 'DEBUG');
|
||||
if (!this.workflowsStore.isInDebugMode) {
|
||||
await this.applyExecutionData(this.$route.params.executionId as string);
|
||||
this.workflowsStore.isInDebugMode = true;
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
async onSourceControlPull() {
|
||||
let workflowId = null as string | null;
|
||||
|
||||
Reference in New Issue
Block a user