🐛 Fix issue that it did not save values for parameters which did get

displayed depending on another parameter with expression
This commit is contained in:
Jan Oberhauser 2021-05-15 17:51:14 -05:00
parent 446c284540
commit fd86229b30
6 changed files with 157 additions and 11 deletions

View file

@ -37,9 +37,6 @@
<script lang="ts"> <script lang="ts">
import Vue from 'vue'; import Vue from 'vue';
import { import {
INodeIssues,
INodeIssueData,
INodeIssueObjectProperty,
INodeTypeDescription, INodeTypeDescription,
INodeParameters, INodeParameters,
INodeProperties, INodeProperties,

View file

@ -464,9 +464,9 @@ export default mixins(
return this.resolveExpression(value as string) as string; return this.resolveExpression(value as string) as string;
}); });
} else if (typeof nodeParameters[key] === 'object') { } else if (typeof nodeParameters[key] === 'object') {
returnData[key] = this.getResolveNodeParameters(nodeParameters[key] as INodeParameters); returnData[key] = this.getResolveNodeParameters(nodeParameters[key] as INodeParameters) as INodeParameters;
} else { } else {
returnData[key] = this.resolveExpression(nodeParameters[key] as string, nodeParameters); returnData[key] = this.resolveExpression(nodeParameters[key] as string, nodeParameters) as NodeParameterValue;
} }
} }
return returnData; return returnData;

View file

@ -80,6 +80,7 @@
import { import {
INodeParameters, INodeParameters,
INodeProperties, INodeProperties,
NodeParameterValue,
} from 'n8n-workflow'; } from 'n8n-workflow';
import { IUpdateInformation } from '@/Interface'; import { IUpdateInformation } from '@/Interface';
@ -110,9 +111,12 @@ export default mixins(
'hideDelete', // boolean 'hideDelete', // boolean
], ],
computed: { computed: {
filteredParameters (): INodeProperties { filteredParameters (): INodeProperties[] {
return this.parameters.filter((parameter: INodeProperties) => this.displayNodeParameter(parameter)); return this.parameters.filter((parameter: INodeProperties) => this.displayNodeParameter(parameter));
}, },
filteredParameterNames (): string[] {
return this.filteredParameters.map(parameter => parameter.name);
},
}, },
methods: { methods: {
multipleValues (parameter: INodeProperties): boolean { multipleValues (parameter: INodeProperties): boolean {
@ -178,7 +182,7 @@ export default mixins(
continue; continue;
} else { } else {
// Contains probably no expression with a missing parameter so resolve // Contains probably no expression with a missing parameter so resolve
nodeValues[key] = this.resolveExpression(rawValues[key], nodeValues); nodeValues[key] = this.resolveExpression(rawValues[key], nodeValues) as NodeParameterValue;
} }
} else { } else {
// Does not contain an expression, add directly // Does not contain an expression, add directly
@ -197,6 +201,23 @@ export default mixins(
this.$emit('valueChanged', parameterData); this.$emit('valueChanged', parameterData);
}, },
}, },
watch: {
filteredParameterNames(newValue, oldValue) {
// After a parameter does not get displayed anymore make sure that its value gets removed
// Is only needed for the edge-case when a parameter gets displayed depending on another field
// which contains an expression.
for (const parameter of oldValue) {
if (!newValue.includes(parameter)) {
const parameterData = {
name: `${this.path}.${parameter}`,
node: this.$store.getters.activeNode.name,
value: undefined,
};
this.$emit('valueChanged', parameterData);
}
}
},
},
beforeCreate: function () { // tslint:disable-line beforeCreate: function () { // tslint:disable-line
// Because we have a circular dependency on CollectionParameter import it here // Because we have a circular dependency on CollectionParameter import it here
// to not break Vue. // to not break Vue.

View file

@ -337,7 +337,6 @@ export const workflowHelpers = mixins(
return nodeData; return nodeData;
}, },
// Executes the given expression and returns its value
resolveExpression (expression: string, siblingParameters: INodeParameters = {}) { resolveExpression (expression: string, siblingParameters: INodeParameters = {}) {
const inputIndex = 0; const inputIndex = 0;
const itemIndex = 0; const itemIndex = 0;

View file

@ -296,6 +296,10 @@ export function displayParameter(nodeValues: INodeParameters, parameter: INodePr
values.push.apply(values, value); values.push.apply(values, value);
} }
if (values.some(v => (typeof v) === 'string' && (v as string).charAt(0) === '=')) {
return true;
}
if (values.length === 0 || !parameter.displayOptions.show[propertyName].some(v => values.includes(v))) { if (values.length === 0 || !parameter.displayOptions.show[propertyName].some(v => values.includes(v))) {
return false; return false;
} }

View file

@ -2814,6 +2814,131 @@ describe('Workflow', () => {
}, },
}, },
}, },
{
description: 'complex type "fixedCollection" with "multipleValues: true". Which contains parameters which get displayed on a parameter with a default expression with relative parameter references.',
input: {
nodePropertiesArray: [
{
displayName: 'Values1',
name: 'values1',
type: 'fixedCollection',
typeOptions: {
multipleValues: true,
},
description: 'The value to set.',
default: {},
options: [
{
displayName: 'Options1',
name: 'options1',
values: [
{
displayName: 'Key',
name: 'key',
type: 'string',
default: '',
},
{
displayName: 'Type',
name: 'type',
type: 'hidden',
default: '={{$parameter["&key"].split("|")[1]}}',
},
{
displayName: 'Title Value',
name: 'titleValue',
displayOptions: {
show: {
type: [
'title',
],
},
},
type: 'string',
default: 'defaultTitle',
},
{
displayName: 'Title Number',
name: 'numberValue',
displayOptions: {
show: {
type: [
'number',
],
},
},
type: 'number',
default: 1,
},
],
},
],
},
],
nodeValues: {
values1: {
options1: [
{
key: 'asdf|title',
titleValue: 'different',
},
],
},
},
},
output: {
noneDisplayedFalse: {
defaultsFalse: {
values1: {
options1: [
{
key: 'asdf|title',
titleValue: 'different',
},
],
},
},
defaultsTrue: {
values1: {
options1: [
{
key: 'asdf|title',
type: '={{$parameter["&key"].split("|")[1]}}',
// This is not great that it displays this theoretically hidden parameter
// but because we can not resolve the values for now
numberValue: 1,
titleValue: 'different',
},
],
},
},
},
noneDisplayedTrue: {
defaultsFalse: {
values1: {
options1: [
{
key: 'asdf|title',
titleValue: 'different',
},
],
},
},
defaultsTrue: {
values1: {
options1: [
{
key: 'asdf|title',
type: '={{$parameter["&key"].split("|")[1]}}',
titleValue: 'different',
numberValue: 1,
},
],
},
},
},
},
},
]; ];