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): Fix operation change failing in certain conditions #8114

Merged
merged 2 commits into from
Dec 22, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions cypress/e2e/5-ndv.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -490,4 +490,19 @@ describe('NDV', () => {
ndv.getters.nodeVersion().should('have.text', 'Function node version 1 (Deprecated)');
ndv.actions.close();
});
it('Should handle mismatched option attributes', () => {
workflowPage.actions.addInitialNodeToCanvas('LDAP', { keepNdvOpen: true, action: 'Create a new entry' });
// Add some attributes in Create operation
cy.getByTestId('parameter-item').contains('Add Attributes').click();
ndv.actions.changeNodeOperation('Update');
// Attributes should be empty after operation change
cy.getByTestId('parameter-item').contains('Currently no items exist').should('exist');
});
it('Should keep RLC values after operation change', () => {
const TEST_DOC_ID = '1111';
workflowPage.actions.addInitialNodeToCanvas('Google Sheets', { keepNdvOpen: true, action: 'Append row in sheet' });
ndv.actions.setRLCValue('documentId', TEST_DOC_ID);
ndv.actions.changeNodeOperation('Update Row');
ndv.getters.resourceLocatorInput('documentId').find('input').should('have.value', TEST_DOC_ID);
});
});
6 changes: 5 additions & 1 deletion cypress/pages/ndv.ts
Original file line number Diff line number Diff line change
Expand Up @@ -246,10 +246,14 @@ export class NDV extends BasePage {
});
this.actions.validateExpressionPreview(fieldName, `node doesn't exist`);
},

openSettings: () => {
this.getters.nodeSettingsTab().click();
},
changeNodeOperation: (operation: string) => {
this.getters.parameterInput('operation').click();
cy.get('.el-select-dropdown__item').contains(new RegExp(`^${operation}$`)).click({ force: true });
this.getters.parameterInput('operation').find('input').should('have.value', operation);
},
};
}

Expand Down
44 changes: 44 additions & 0 deletions packages/editor-ui/src/components/NodeSettings.vue
Original file line number Diff line number Diff line change
Expand Up @@ -864,6 +864,12 @@ export default defineComponent({
} else {
set(nodeParameters as object, parameterPath, newValue);
}
// If value is updated, remove parameter values that have invalid options
// so getNodeParameters checks don't fail
this.removeMismatchedOptionValues(nodeType, nodeParameters, {
name: parameterPath,
value: newValue,
});
}

// Get the parameters with the now new defaults according to the
Expand Down Expand Up @@ -919,6 +925,44 @@ export default defineComponent({
this.workflowsStore.setNodeValue(updateInformation);
}
},
/**
* Removes node values that are not valid options for the given parameter.
* This can happen when there are multiple node parameters with the same name
* but different options and display conditions
* @param nodeType The node type description
* @param nodeParameterValues Current node parameter values
* @param updatedParameter The parameter that was updated. Will be used to determine which parameters to remove based on their display conditions and option values
*/
removeMismatchedOptionValues(
nodeType: INodeTypeDescription,
nodeParameterValues: INodeParameters | null,
updatedParameter: { name: string; value: NodeParameterValue },
) {
nodeType.properties.forEach((prop) => {
const displayOptions = prop.displayOptions;
// Not processing parameters that are not set or don't have options
if (!nodeParameterValues?.hasOwnProperty(prop.name) || !displayOptions || !prop.options) {
return;
}
// Only process the parameters that should be hidden
const showCondition = displayOptions.show?.[updatedParameter.name];
const hideCondition = displayOptions.hide?.[updatedParameter.name];
if (showCondition === undefined && hideCondition === undefined) {
return;
}
// Every value should be a possible option
const hasValidOptions = Object.keys(nodeParameterValues).every(
(key) => (prop.options ?? []).find((option) => option.name === key) !== undefined,
);
if (
!hasValidOptions ||
showCondition !== updatedParameter.value ||
hideCondition === updatedParameter.value
) {
unset(nodeParameterValues as object, prop.name);
}
});
},
/**
* Sets the values of the active node in the internal settings variables
*/
Expand Down
Loading