Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

1 change: 1 addition & 0 deletions packages/editor-ui/src/Interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,7 @@ export default defineComponent({
const parameterData = {
name: this.getPropertyPath(optionName),
value: this.mutableValues[optionName],
type: 'optionsOrderChanged',
};

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

this.$emit('valueChanged', parameterData);
Expand Down
18 changes: 18 additions & 0 deletions packages/editor-ui/src/components/NodeSettings.vue
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand All @@ -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',
Expand All @@ -238,10 +240,12 @@ export default defineComponent({
setup() {
const nodeHelpers = useNodeHelpers();
const externalHooks = useExternalHooks();
const { showMessage } = useToast();

return {
externalHooks,
nodeHelpers,
showMessage,
};
},
computed: {
Expand Down Expand Up @@ -853,6 +857,20 @@ export default defineComponent({
return;
}

if (
parameterData.type &&
SHOULD_CLEAR_NODE_OUTPUTS[nodeType.name] &&
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Eslint warning here: Prefer using an optional chain expression instead, as it's more concise and easier to read.eslint[@typescript-eslint/prefer-optional-chain](https://typescript-eslint.io/rules/prefer-optional-chain)

SHOULD_CLEAR_NODE_OUTPUTS[nodeType.name].eventTypes.includes(parameterData.type) &&
SHOULD_CLEAR_NODE_OUTPUTS[nodeType.name].parameterPaths.includes(parameterData.name)
) {
this.workflowsStore.clearNodeOutgoingConnections(node.name);
this.showMessage({
OlegIvaniv marked this conversation as resolved.
Show resolved Hide resolved
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,
Expand Down
14 changes: 14 additions & 0 deletions packages/editor-ui/src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -654,6 +654,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 = [
Expand Down
2 changes: 2 additions & 0 deletions packages/editor-ui/src/plugins/i18n/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -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 was cleared",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Order of parameters changed, outgoing connections were cleared.

"nodeSettings.nodeVersion": "{node} node version {version}",
"nodeView.addNode": "Add node",
"nodeView.openNodesPanel": "Open nodes panel",
Expand Down
10 changes: 10 additions & 0 deletions packages/editor-ui/src/stores/workflows.store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,16 @@ export const useWorkflowsStore = defineStore(STORES.WORKFLOWS, {
return {};
};
},
clearNodeOutgoingConnections() {
const uiStore = useUIStore();
return (nodeName: string): void => {
if (this.workflow.connections.hasOwnProperty(nodeName)) {
this.workflow.connections[nodeName] = {};
uiStore.stateIsDirty = true;
return;
}
};
},
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This shouldn't be a getter but rather an action

isNodeInOutgoingNodeConnections() {
return (firstNode: string, secondNode: string): boolean => {
const firstNodeConnections = this.outgoingConnectionsByNodeName(firstNode);
Expand Down