mirror of
https://github.com/n8n-io/n8n.git
synced 2025-03-05 20:50:17 -08:00
🐛 Fix parameter update bug with identically named parameters
This commit is contained in:
parent
0c28799dac
commit
91bff6e4f6
|
@ -30,6 +30,7 @@
|
|||
"@types/file-saver": "^2.0.1",
|
||||
"@types/jest": "^23.3.2",
|
||||
"@types/lodash.get": "^4.4.5",
|
||||
"@types/lodash.set": "^4.3.6",
|
||||
"@types/quill": "^2.0.1",
|
||||
"@vue/cli-plugin-babel": "^3.8.0",
|
||||
"@vue/cli-plugin-e2e-cypress": "^3.8.0",
|
||||
|
@ -54,6 +55,7 @@
|
|||
"jsplumb": "^2.10.0",
|
||||
"lodash.debounce": "^4.0.8",
|
||||
"lodash.get": "^4.4.2",
|
||||
"lodash.set": "^4.3.2",
|
||||
"n8n-workflow": "^0.3.0",
|
||||
"node-sass": "^4.12.0",
|
||||
"quill": "^2.0.0-dev.3",
|
||||
|
@ -67,8 +69,8 @@
|
|||
"vue-cli-plugin-webpack-bundle-analyzer": "^1.3.0",
|
||||
"vue-json-pretty": "^1.4.1",
|
||||
"vue-router": "^3.0.6",
|
||||
"vue-template-compiler": "^2.5.17",
|
||||
"vue-typed-mixins": "^0.1.0",
|
||||
"vuex": "^3.1.1",
|
||||
"vue-template-compiler": "^2.5.17"
|
||||
"vuex": "^3.1.1"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -116,7 +116,7 @@ export default mixins(genericHelpers)
|
|||
deleteOption (optionName: string, index?: number) {
|
||||
const parameterData = {
|
||||
name: this.getPropertyPath(optionName, index),
|
||||
value: null,
|
||||
value: undefined,
|
||||
};
|
||||
|
||||
this.$emit('valueChanged', parameterData);
|
||||
|
|
|
@ -89,7 +89,7 @@ export default mixins(genericHelpers)
|
|||
deleteItem (index: number) {
|
||||
const parameterData = {
|
||||
name: this.getPath(index),
|
||||
value: null,
|
||||
value: undefined,
|
||||
};
|
||||
|
||||
this.$emit('valueChanged', parameterData);
|
||||
|
|
|
@ -82,7 +82,7 @@ import ParameterInputFull from '@/components/ParameterInputFull.vue';
|
|||
import ParameterInputList from '@/components/ParameterInputList.vue';
|
||||
import NodeCredentials from '@/components/NodeCredentials.vue';
|
||||
import NodeWebhooks from '@/components/NodeWebhooks.vue';
|
||||
import { get } from 'lodash';
|
||||
import { get, set } from 'lodash';
|
||||
|
||||
import { genericHelpers } from '@/components/mixins/genericHelpers';
|
||||
import { nodeHelpers } from '@/components/mixins/nodeHelpers';
|
||||
|
@ -235,7 +235,7 @@ export default mixins(
|
|||
Vue.set(this.nodeValues, lastNamePart, value);
|
||||
}
|
||||
} else {
|
||||
// Data is on lewer level
|
||||
// Data is on lower level
|
||||
if (value === null) {
|
||||
// Property should be deleted
|
||||
// @ts-ignore
|
||||
|
@ -294,52 +294,102 @@ export default mixins(
|
|||
newValue = get(this.nodeValues, parameterData.name) as NodeParameterValue;
|
||||
}
|
||||
|
||||
if (newValue !== undefined) {
|
||||
// Save the node name before we commit the change because
|
||||
// we need the old name to rename the node properly
|
||||
const nodeNameBefore = parameterData.node || this.node.name;
|
||||
const node = this.$store.getters.nodeByName(nodeNameBefore);
|
||||
// Save the node name before we commit the change because
|
||||
// we need the old name to rename the node properly
|
||||
const nodeNameBefore = parameterData.node || this.node.name;
|
||||
const node = this.$store.getters.nodeByName(nodeNameBefore);
|
||||
if (parameterData.name === 'name') {
|
||||
// Name of node changed so we have to set also the new node name as active
|
||||
|
||||
this.setValue(parameterData.name, newValue);
|
||||
// Update happens in NodeView so emit event
|
||||
const sendData = {
|
||||
value: newValue,
|
||||
oldValue: nodeNameBefore,
|
||||
name: parameterData.name,
|
||||
};
|
||||
this.$emit('valueChanged', sendData);
|
||||
|
||||
this.$store.commit('setActiveNode', newValue);
|
||||
} else if (parameterData.name === 'color') {
|
||||
// Color of node changed
|
||||
|
||||
// Update color in settings
|
||||
Vue.set(this.nodeValues, 'color', newValue);
|
||||
// Update color in vuex
|
||||
const updateInformation = {
|
||||
name: node.name,
|
||||
key: parameterData.name,
|
||||
key: 'color',
|
||||
value: newValue,
|
||||
};
|
||||
this.$store.commit('setNodeValue', updateInformation);
|
||||
} else {
|
||||
// Everything else are node parameters
|
||||
|
||||
if (parameterData.name === 'name') {
|
||||
// Name of node changed so we have to set also the new node name as active
|
||||
const nodeType = this.$store.getters.nodeType(node.type);
|
||||
|
||||
const sendData = {
|
||||
value: newValue,
|
||||
oldValue: nodeNameBefore,
|
||||
name: parameterData.name,
|
||||
};
|
||||
this.$emit('valueChanged', sendData);
|
||||
// Get only the parameters which are different to the defaults
|
||||
let nodeParameters = NodeHelpers.getNodeParameters(nodeType.properties, node.parameters, false, false);
|
||||
|
||||
this.$store.commit('setActiveNode', newValue);
|
||||
} else {
|
||||
// For all changes except renames we commit the change. For
|
||||
// renames that happens in NodeView
|
||||
this.$store.commit('setNodeParameter', updateInformation);
|
||||
// Copy the data because it is the data of vuex so make sure that
|
||||
// we do not edit it directly
|
||||
nodeParameters = JSON.parse(JSON.stringify(nodeParameters));
|
||||
|
||||
const nodeType = this.$store.getters.nodeType(node.type);
|
||||
const fullNodeIssues: INodeIssues | null = NodeHelpers.getNodeParametersIssues(nodeType.properties, node);
|
||||
// Remove the 'parameters.' from the beginning to just have the
|
||||
// actual parameter name
|
||||
const parameterPath = parameterData.name.split('.').slice(1).join('.');
|
||||
|
||||
let newIssues: INodeIssueObjectProperty | null = null;
|
||||
if (fullNodeIssues !== null) {
|
||||
newIssues = fullNodeIssues.parameters!;
|
||||
// Check if the path is supposed to change an array and if so get
|
||||
// the needed data like path and index
|
||||
const parameterPathArray = parameterPath.match(/(.*)\[(\d)\]$/);
|
||||
|
||||
// Apply the new value
|
||||
if (parameterData.value === undefined && parameterPathArray !== null) {
|
||||
// Delete array item
|
||||
const path = parameterPathArray[1];
|
||||
const index = parameterPathArray[2];
|
||||
const data = get(nodeParameters, path);
|
||||
|
||||
if (Array.isArray(data)) {
|
||||
data.splice(parseInt(index, 10), 1);
|
||||
Vue.set(nodeParameters as object, path, data);
|
||||
}
|
||||
|
||||
this.$store.commit('setNodeIssue', {
|
||||
node: node.name,
|
||||
type: 'parameters',
|
||||
value: newIssues,
|
||||
} as INodeIssueData);
|
||||
|
||||
this.updateNodeCredentialIssues(node);
|
||||
} else {
|
||||
// For everything else
|
||||
set(nodeParameters as object, parameterPath, newValue);
|
||||
}
|
||||
|
||||
// Get the parameters with the now new defaults according to the
|
||||
// from the user actually defined parameters
|
||||
nodeParameters = NodeHelpers.getNodeParameters(nodeType.properties, nodeParameters as INodeParameters, true, false);
|
||||
|
||||
for (const key of Object.keys(nodeParameters as object)) {
|
||||
if (nodeParameters && nodeParameters[key] !== null && nodeParameters[key] !== undefined) {
|
||||
this.setValue(`parameters.${key}`, nodeParameters[key] as string);
|
||||
}
|
||||
}
|
||||
|
||||
// Update the data in vuex
|
||||
const updateInformation = {
|
||||
name: node.name,
|
||||
value: nodeParameters,
|
||||
};
|
||||
this.$store.commit('setNodeParameters', updateInformation);
|
||||
|
||||
// All data got updated everywhere so update now the issues
|
||||
const fullNodeIssues: INodeIssues | null = NodeHelpers.getNodeParametersIssues(nodeType.properties, node);
|
||||
|
||||
let newIssues: INodeIssueObjectProperty | null = null;
|
||||
if (fullNodeIssues !== null) {
|
||||
newIssues = fullNodeIssues.parameters!;
|
||||
}
|
||||
|
||||
this.$store.commit('setNodeIssue', {
|
||||
node: node.name,
|
||||
type: 'parameters',
|
||||
value: newIssues,
|
||||
} as INodeIssueData);
|
||||
|
||||
this.updateNodeCredentialIssues(node);
|
||||
}
|
||||
},
|
||||
/**
|
||||
|
|
|
@ -141,7 +141,7 @@ export default mixins(
|
|||
deleteOption (optionName: string): void {
|
||||
const parameterData = {
|
||||
name: this.getPath(optionName),
|
||||
value: null,
|
||||
value: undefined,
|
||||
};
|
||||
|
||||
// TODO: If there is only one option it should delete the whole one
|
||||
|
|
|
@ -348,7 +348,7 @@ export const store = new Vuex.Store({
|
|||
}
|
||||
}
|
||||
},
|
||||
setNodeParameter (state, updateInformation: IUpdateInformation) {
|
||||
setNodeValue (state, updateInformation: IUpdateInformation) {
|
||||
// Find the node that should be updated
|
||||
const node = state.workflow.nodes.find(node => {
|
||||
return node.name === updateInformation.name;
|
||||
|
@ -358,55 +358,19 @@ export const store = new Vuex.Store({
|
|||
throw new Error(`Node with the name "${updateInformation.name}" could not be found to set parameter.`);
|
||||
}
|
||||
|
||||
const nameParts = updateInformation.key.split('.');
|
||||
let lastNamePart = nameParts.pop();
|
||||
Vue.set(node, updateInformation.key, updateInformation.value);
|
||||
},
|
||||
setNodeParameters (state, updateInformation: IUpdateInformation) {
|
||||
// Find the node that should be updated
|
||||
const node = state.workflow.nodes.find(node => {
|
||||
return node.name === updateInformation.name;
|
||||
});
|
||||
|
||||
let isArray = false;
|
||||
if (lastNamePart !== undefined && lastNamePart.includes('[')) {
|
||||
// It incldues an index so we have to extract it
|
||||
const lastNameParts = lastNamePart.match(/(.*)\[(\d+)\]$/);
|
||||
if (lastNameParts) {
|
||||
nameParts.push(lastNameParts[1]);
|
||||
lastNamePart = lastNameParts[2];
|
||||
isArray = true;
|
||||
}
|
||||
if (node === undefined || node === null) {
|
||||
throw new Error(`Node with the name "${updateInformation.name}" could not be found to set parameter.`);
|
||||
}
|
||||
|
||||
// Set the value via Vue.set that everything updates correctly in the UI
|
||||
|
||||
if (nameParts.length === 0) {
|
||||
// Data is on top level
|
||||
if (updateInformation.value === null) {
|
||||
// Property should be deleted
|
||||
// @ts-ignore
|
||||
Vue.delete(node, lastNamePart);
|
||||
} else {
|
||||
// Value should be set
|
||||
// @ts-ignore
|
||||
Vue.set(node, lastNamePart, updateInformation.value);
|
||||
}
|
||||
} else {
|
||||
// Data is on lewer level
|
||||
if (updateInformation.value === null) {
|
||||
// Property should be deleted
|
||||
let tempValue = get(node, nameParts.join('.'));
|
||||
|
||||
Vue.delete(tempValue, lastNamePart as string);
|
||||
|
||||
if (isArray === true && tempValue.length === 0) {
|
||||
// If a value from an array got delete and no values are left
|
||||
// delete also the parent
|
||||
lastNamePart = nameParts.pop();
|
||||
tempValue = get(node, nameParts.join('.'));
|
||||
|
||||
Vue.delete(tempValue, lastNamePart as string);
|
||||
}
|
||||
} else {
|
||||
// Value should be set
|
||||
Vue.set(get(node, nameParts.join('.')), lastNamePart as string, updateInformation.value);
|
||||
// Vue.set(get(node, nameParts.join('.')), lastNamePart as string, JSON.parse(JSON.stringify(updateInformation.value)));
|
||||
}
|
||||
}
|
||||
Vue.set(node, 'parameters', updateInformation.value);
|
||||
},
|
||||
|
||||
// Node-Index
|
||||
|
@ -460,10 +424,10 @@ export const store = new Vuex.Store({
|
|||
Vue.set(state, 'endpointWebhookTest', endpointWebhookTest);
|
||||
},
|
||||
|
||||
setSaveDataErrorExecution(state, newValue: string) {
|
||||
setSaveDataErrorExecution (state, newValue: string) {
|
||||
Vue.set(state, 'saveDataErrorExecution', newValue);
|
||||
},
|
||||
setSaveDataSuccessExecution(state, newValue: string) {
|
||||
setSaveDataSuccessExecution (state, newValue: string) {
|
||||
Vue.set(state, 'saveDataSuccessExecution', newValue);
|
||||
},
|
||||
setSaveManualExecutions (state, saveManualExecutions: boolean) {
|
||||
|
|
|
@ -1417,7 +1417,7 @@ export default mixins(
|
|||
if (nodeType !== null) {
|
||||
let nodeParameters = null;
|
||||
try {
|
||||
nodeParameters = NodeHelpers.getNodeParameters(nodeType.properties, node.parameters, true, true);
|
||||
nodeParameters = NodeHelpers.getNodeParameters(nodeType.properties, node.parameters, true, false);
|
||||
} catch (e) {
|
||||
console.error(`There was a problem loading the node-parameters of node: "${node.name}"`);
|
||||
console.error(e);
|
||||
|
|
Loading…
Reference in a new issue