fix(editor): Drop outgoing connections on order changed event for nodes with dynamic outputs (#9055)

This commit is contained in:
Michael Kret
2024-04-09 04:46:52 +03:00
committed by GitHub
parent 936682eeaa
commit 3dd70a17e2
8 changed files with 304 additions and 2 deletions

View File

@@ -139,6 +139,7 @@ export interface IUpdateInformation {
| INodeParameters; // with null makes problems in NodeSettings.vue
node?: string;
oldValue?: string | number;
type?: 'optionsOrderChanged';
}
export interface INodeUpdatePropertiesInformation {

View File

@@ -254,6 +254,7 @@ export default defineComponent({
const parameterData = {
name: this.getPropertyPath(optionName),
value: this.mutableValues[optionName],
type: 'optionsOrderChanged',
};
this.$emit('valueChanged', parameterData);
@@ -270,6 +271,7 @@ export default defineComponent({
const parameterData = {
name: this.getPropertyPath(optionName),
value: this.mutableValues[optionName],
type: 'optionsOrderChanged',
};
this.$emit('valueChanged', parameterData);

View File

@@ -200,6 +200,7 @@ import {
CUSTOM_NODES_DOCS_URL,
MAIN_NODE_PANEL_WIDTH,
IMPORT_CURL_MODAL_KEY,
SHOULD_CLEAR_NODE_OUTPUTS,
} from '@/constants';
import NodeTitle from '@/components/NodeTitle.vue';
@@ -223,6 +224,7 @@ import { useCredentialsStore } from '@/stores/credentials.store';
import type { EventBus } from 'n8n-design-system';
import { useExternalHooks } from '@/composables/useExternalHooks';
import { useNodeHelpers } from '@/composables/useNodeHelpers';
import { useToast } from '@/composables/useToast';
export default defineComponent({
name: 'NodeSettings',
@@ -238,10 +240,12 @@ export default defineComponent({
setup() {
const nodeHelpers = useNodeHelpers();
const externalHooks = useExternalHooks();
const { showMessage } = useToast();
return {
externalHooks,
nodeHelpers,
showMessage,
};
},
computed: {
@@ -853,6 +857,20 @@ export default defineComponent({
return;
}
if (
parameterData.type &&
this.workflowsStore.nodeHasOutputConnection(node.name) &&
SHOULD_CLEAR_NODE_OUTPUTS[nodeType.name]?.eventTypes.includes(parameterData.type) &&
SHOULD_CLEAR_NODE_OUTPUTS[nodeType.name]?.parameterPaths.includes(parameterData.name)
) {
this.workflowsStore.removeAllNodeConnection(node, { preserveInputConnections: true });
this.showMessage({
type: 'warning',
title: this.$locale.baseText('nodeSettings.outputCleared.title'),
message: this.$locale.baseText('nodeSettings.outputCleared.message'),
});
}
// Get only the parameters which are different to the defaults
let nodeParameters = NodeHelpers.getNodeParameters(
nodeType.properties,

View File

@@ -653,6 +653,20 @@ export const MFA_AUTHENTICATION_RECOVERY_CODE_INPUT_MAX_LENGTH = 36;
export const NODE_TYPES_EXCLUDED_FROM_OUTPUT_NAME_APPEND = [FILTER_NODE_TYPE, SWITCH_NODE_TYPE];
type ClearOutgoingConnectonsEvents = {
[nodeName: string]: {
parameterPaths: string[];
eventTypes: string[];
};
};
export const SHOULD_CLEAR_NODE_OUTPUTS: ClearOutgoingConnectonsEvents = {
[SWITCH_NODE_TYPE]: {
parameterPaths: ['parameters.rules.values'],
eventTypes: ['optionsOrderChanged'],
},
};
export const ALLOWED_HTML_ATTRIBUTES = ['href', 'name', 'target', 'title', 'class', 'id', 'style'];
export const ALLOWED_HTML_TAGS = [

View File

@@ -1093,6 +1093,8 @@
"nodeSettings.latest": "Latest",
"nodeSettings.deprecated": "Deprecated",
"nodeSettings.latestVersion": "Latest version: {version}",
"nodeSettings.outputCleared.title": "Parameters changed",
"nodeSettings.outputCleared.message": "Order of parameters changed, outgoing connections were cleared",
"nodeSettings.nodeVersion": "{node} node version {version}",
"nodeView.addNode": "Add node",
"nodeView.openNodesPanel": "Open nodes panel",

View File

@@ -200,6 +200,12 @@ export const useWorkflowsStore = defineStore(STORES.WORKFLOWS, {
return {};
};
},
nodeHasOutputConnection() {
return (nodeName: string): boolean => {
if (this.workflow.connections.hasOwnProperty(nodeName)) return true;
return false;
};
},
isNodeInOutgoingNodeConnections() {
return (firstNode: string, secondNode: string): boolean => {
const firstNodeConnections = this.outgoingConnectionsByNodeName(firstNode);
@@ -841,15 +847,19 @@ export const useWorkflowsStore = defineStore(STORES.WORKFLOWS, {
this.workflow.connections = {};
},
removeAllNodeConnection(node: INodeUi): void {
removeAllNodeConnection(
node: INodeUi,
{ preserveInputConnections = false, preserveOutputConnections = false } = {},
): void {
const uiStore = useUIStore();
uiStore.stateIsDirty = true;
// Remove all source connections
if (this.workflow.connections.hasOwnProperty(node.name)) {
if (!preserveOutputConnections && this.workflow.connections.hasOwnProperty(node.name)) {
delete this.workflow.connections[node.name];
}
// Remove all destination connections
if (preserveInputConnections) return;
const indexesToRemove = [];
let sourceNode: string,
type: string,