feat(editor): Add support for loadOptionsDependsOn to RLC (#6101)

* feat(editor): Add support for `loadOptionsDependsOn` to the Resource Locator component
* 🔥 Removing leftover log
*  Added e2e tests for ResourceLocator component
This commit is contained in:
Milorad FIlipović 2023-04-28 12:14:31 +02:00 committed by GitHub
parent 2e73f4abd0
commit b17d5f9aa0
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 97 additions and 3 deletions

View file

@ -0,0 +1,58 @@
import { WorkflowPage, NDV, CredentialsModal } from '../pages';
const workflowPage = new WorkflowPage();
const ndv = new NDV();
const credentialsModal = new CredentialsModal();
const NO_CREDENTIALS_MESSAGE = 'Please add your credential';
const INVALID_CREDENTIALS_MESSAGE = 'Please check your credential';
describe('Resource Locator', () => {
before(() => {
cy.resetAll();
cy.skipSetup();
});
beforeEach(() => {
workflowPage.actions.visit();
});
it('should render both RLC components in google sheets', () => {
workflowPage.actions.addInitialNodeToCanvas('Manual');
workflowPage.actions.addNodeToCanvas('Google Sheets', true, true);
ndv.getters.resourceLocator('documentId').should('be.visible');
ndv.getters.resourceLocator('sheetName').should('be.visible');
});
it('should show appropriate error when credentials are not set', () => {
workflowPage.actions.addInitialNodeToCanvas('Manual');
workflowPage.actions.addNodeToCanvas('Google Sheets', true, true);
ndv.getters.resourceLocator('documentId').should('be.visible');
ndv.getters.resourceLocatorInput('documentId').click();
ndv.getters.resourceLocatorErrorMessage().should('contain', NO_CREDENTIALS_MESSAGE);
});
it('should show appropriate error when credentials are not valid', () => {
workflowPage.actions.addInitialNodeToCanvas('Manual');
workflowPage.actions.addNodeToCanvas('Google Sheets', true, true);
workflowPage.getters.nodeCredentialsSelect().click();
// Add oAuth credentials
workflowPage.getters.nodeCredentialsSelect().find('li').last().click();
credentialsModal.getters.credentialsEditModal().should('be.visible');
credentialsModal.getters.credentialAuthTypeRadioButtons().should('have.length', 2);
credentialsModal.getters.credentialAuthTypeRadioButtons().first().click();
credentialsModal.actions.fillCredentialsForm();
cy.get('.el-message-box').find('button').contains('Close').click();
ndv.getters.resourceLocatorInput('documentId').click();
ndv.getters.resourceLocatorErrorMessage().should('contain', INVALID_CREDENTIALS_MESSAGE);
});
it('should reset resource locator when dependent field is changed', () => {
workflowPage.actions.addInitialNodeToCanvas('Manual');
workflowPage.actions.addNodeToCanvas('Google Sheets', true, true);
ndv.actions.setRLCValue('documentId', '123');
ndv.actions.setRLCValue('sheetName', '123');
ndv.actions.setRLCValue('documentId', '321');
ndv.getters.resourceLocatorInput('sheetName').should('have.value', '');
});
});

View file

@ -51,6 +51,11 @@ export class NDV extends BasePage {
inputHoveringItem: () => this.getters.inputPanel().findChildByTestId('hovering-item'), inputHoveringItem: () => this.getters.inputPanel().findChildByTestId('hovering-item'),
outputBranches: () => this.getters.outputPanel().findChildByTestId('branches'), outputBranches: () => this.getters.outputPanel().findChildByTestId('branches'),
inputBranches: () => this.getters.inputPanel().findChildByTestId('branches'), inputBranches: () => this.getters.inputPanel().findChildByTestId('branches'),
resourceLocator: (paramName: string) => cy.getByTestId(`resource-locator-${paramName}`),
resourceLocatorInput: (paramName: string) => this.getters.resourceLocator(paramName).find('[data-test-id="rlc-input-container"]'),
resourceLocatorDropdown: (paramName: string) => this.getters.resourceLocator(paramName).find('[data-test-id="resource-locator-dropdown"]'),
resourceLocatorErrorMessage: () => cy.getByTestId('rlc-error-container'),
resourceLocatorModeSelector: (paramName: string) => this.getters.resourceLocator(paramName).find('[data-test-id="rlc-mode-selector"]'),
}; };
actions = { actions = {
@ -148,5 +153,10 @@ export class NDV extends BasePage {
switchIntputBranch: (name: string) => { switchIntputBranch: (name: string) => {
this.getters.inputBranches().get('span').contains(name).click(); this.getters.inputBranches().get('span').contains(name).click();
}, },
setRLCValue: (paramName: string, value: string) => {
this.getters.resourceLocatorModeSelector(paramName).click();
this.getters.resourceLocatorModeSelector(paramName).find('li').last().click();
this.getters.resourceLocatorInput(paramName).type(value);
}
}; };
} }

View file

@ -18,6 +18,7 @@
ref="resourceLocator" ref="resourceLocator"
:parameter="parameter" :parameter="parameter"
:value="value" :value="value"
:dependentParametersValues="dependentParametersValues"
:displayTitle="displayTitle" :displayTitle="displayTitle"
:expressionDisplayValue="expressionDisplayValue" :expressionDisplayValue="expressionDisplayValue"
:expressionComputedValue="expressionEvaluated" :expressionComputedValue="expressionEvaluated"

View file

@ -1,5 +1,9 @@
<template> <template>
<div class="resource-locator" ref="container"> <div
class="resource-locator"
ref="container"
:data-test-id="`resource-locator-${parameter.name}`"
>
<resource-locator-dropdown <resource-locator-dropdown
:value="value ? value.value : ''" :value="value ? value.value : ''"
:show="showResourceDropdown" :show="showResourceDropdown"
@ -18,7 +22,7 @@
ref="dropdown" ref="dropdown"
> >
<template #error> <template #error>
<div :class="$style.error"> <div :class="$style.error" data-test-id="rlc-error-container">
<n8n-text color="text-dark" align="center" tag="div"> <n8n-text color="text-dark" align="center" tag="div">
{{ $locale.baseText('resourceLocator.mode.list.error.title') }} {{ $locale.baseText('resourceLocator.mode.list.error.title') }}
</n8n-text> </n8n-text>
@ -47,6 +51,7 @@
:disabled="isReadOnly" :disabled="isReadOnly"
@change="onModeSelected" @change="onModeSelected"
:placeholder="$locale.baseText('resourceLocator.modeSelector.placeholder')" :placeholder="$locale.baseText('resourceLocator.modeSelector.placeholder')"
data-test-id="rlc-mode-selector"
> >
<n8n-option <n8n-option
v-for="mode in parameter.modes" v-for="mode in parameter.modes"
@ -64,7 +69,7 @@
</n8n-select> </n8n-select>
</div> </div>
<div :class="$style.inputContainer"> <div :class="$style.inputContainer" data-test-id="rlc-input-container">
<draggable-target <draggable-target
type="mapping" type="mapping"
:disabled="hasOnlyListMode" :disabled="hasOnlyListMode"
@ -101,6 +106,7 @@
:placeholder="inputPlaceholder" :placeholder="inputPlaceholder"
type="text" type="text"
ref="input" ref="input"
data-test-id="rlc-input"
@input="onInputChange" @input="onInputChange"
@focus="onInputFocus" @focus="onInputFocus"
@blur="onInputBlur" @blur="onInputBlur"
@ -212,6 +218,10 @@ export default mixins(debounceHelper, workflowHelpers, nodeHelpers).extend({
type: Array as PropType<string[]>, type: Array as PropType<string[]>,
default: () => [], default: () => [],
}, },
dependentParametersValues: {
type: [String, null] as PropType<string | null>,
default: null,
},
displayTitle: { displayTitle: {
type: String, type: String,
default: '', default: '',
@ -448,6 +458,17 @@ export default mixins(debounceHelper, workflowHelpers, nodeHelpers).extend({
this.$emit('input', { ...this.value, __regex: mode.extractValue.regex }); this.$emit('input', { ...this.value, __regex: mode.extractValue.regex });
} }
}, },
dependentParametersValues() {
// Reset value if dependent parameters change
if (this.value && isResourceLocatorValue(this.value) && this.value.value !== '') {
this.$emit('input', {
...this.value,
cachedResultName: '',
cachedResultUrl: '',
value: '',
});
}
},
}, },
mounted() { mounted() {
this.$on('refreshList', this.refreshList); this.$on('refreshList', this.refreshList);

View file

@ -5,6 +5,7 @@
:popper-class="$style.popover" :popper-class="$style.popover"
:value="show" :value="show"
trigger="manual" trigger="manual"
data-test-id="resource-locator-dropdown"
v-click-outside="onClickOutside" v-click-outside="onClickOutside"
> >
<div :class="$style.messageContainer" v-if="errorView"> <div :class="$style.messageContainer" v-if="errorView">

View file

@ -139,6 +139,9 @@ export const descriptions: INodeProperties[] = [
default: { mode: 'list', value: '' }, default: { mode: 'list', value: '' },
// default: '', //empty string set to progresivly reveal fields // default: '', //empty string set to progresivly reveal fields
required: true, required: true,
typeOptions: {
loadOptionsDependsOn: ['documentId.value'],
},
modes: [ modes: [
{ {
displayName: 'From List', displayName: 'From List',