mirror of
https://github.com/n8n-io/n8n.git
synced 2024-11-09 22:24:05 -08:00
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:
parent
2e73f4abd0
commit
b17d5f9aa0
58
cypress/e2e/26-resource-locator.cy.ts
Normal file
58
cypress/e2e/26-resource-locator.cy.ts
Normal 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', '');
|
||||||
|
});
|
||||||
|
});
|
|
@ -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);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -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"
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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">
|
||||||
|
|
|
@ -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',
|
||||||
|
|
Loading…
Reference in a new issue