mirror of
https://github.com/n8n-io/n8n.git
synced 2025-01-12 05:17:28 -08:00
fix(editor): Show error state correctly in options parameter with remote options (#9836)
This commit is contained in:
parent
803895360c
commit
5bc58efde9
|
@ -1,5 +1,5 @@
|
||||||
import { getVisibleSelect } from '../utils';
|
import { getVisibleSelect } from '../utils';
|
||||||
import { MANUAL_TRIGGER_NODE_DISPLAY_NAME } from '../constants';
|
import { MANUAL_TRIGGER_NODE_DISPLAY_NAME, NOTION_NODE_NAME } from '../constants';
|
||||||
import { NDV, WorkflowPage } from '../pages';
|
import { NDV, WorkflowPage } from '../pages';
|
||||||
import { NodeCreator } from '../pages/features/node-creator';
|
import { NodeCreator } from '../pages/features/node-creator';
|
||||||
import { clickCreateNewCredential } from '../composables/ndv';
|
import { clickCreateNewCredential } from '../composables/ndv';
|
||||||
|
@ -699,6 +699,23 @@ describe('NDV', () => {
|
||||||
ndv.getters.parameterInput('operation').find('input').should('have.value', 'Delete');
|
ndv.getters.parameterInput('operation').find('input').should('have.value', 'Delete');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('Should show error state when remote options cannot be fetched', () => {
|
||||||
|
cy.intercept('POST', '/rest/dynamic-node-parameters/options', { statusCode: 500 }).as(
|
||||||
|
'parameterOptions',
|
||||||
|
);
|
||||||
|
|
||||||
|
workflowPage.actions.addInitialNodeToCanvas(NOTION_NODE_NAME, {
|
||||||
|
keepNdvOpen: true,
|
||||||
|
action: 'Update a database page',
|
||||||
|
});
|
||||||
|
|
||||||
|
ndv.actions.addItemToFixedCollection('propertiesUi');
|
||||||
|
ndv.getters
|
||||||
|
.parameterInput('key')
|
||||||
|
.find('input')
|
||||||
|
.should('have.value', 'Error fetching options from Notion');
|
||||||
|
});
|
||||||
|
|
||||||
it('Should open appropriate node creator after clicking on connection hint link', () => {
|
it('Should open appropriate node creator after clicking on connection hint link', () => {
|
||||||
const nodeCreator = new NodeCreator();
|
const nodeCreator = new NodeCreator();
|
||||||
const hintMapper = {
|
const hintMapper = {
|
||||||
|
|
|
@ -131,6 +131,8 @@ export class NDV extends BasePage {
|
||||||
nodeRunErrorIndicator: () => cy.getByTestId('node-run-info-danger'),
|
nodeRunErrorIndicator: () => cy.getByTestId('node-run-info-danger'),
|
||||||
nodeRunErrorMessage: () => cy.getByTestId('node-error-message'),
|
nodeRunErrorMessage: () => cy.getByTestId('node-error-message'),
|
||||||
nodeRunErrorDescription: () => cy.getByTestId('node-error-description'),
|
nodeRunErrorDescription: () => cy.getByTestId('node-error-description'),
|
||||||
|
fixedCollectionParameter: (paramName: string) =>
|
||||||
|
cy.getByTestId(`fixed-collection-${paramName}`),
|
||||||
schemaViewNode: () => cy.getByTestId('run-data-schema-node'),
|
schemaViewNode: () => cy.getByTestId('run-data-schema-node'),
|
||||||
schemaViewNodeName: () => cy.getByTestId('run-data-schema-node-name'),
|
schemaViewNodeName: () => cy.getByTestId('run-data-schema-node-name'),
|
||||||
};
|
};
|
||||||
|
@ -307,6 +309,9 @@ export class NDV extends BasePage {
|
||||||
expressionSelectPrevItem: () => {
|
expressionSelectPrevItem: () => {
|
||||||
this.getters.inlineExpressionEditorItemPrevButton().click();
|
this.getters.inlineExpressionEditorItemPrevButton().click();
|
||||||
},
|
},
|
||||||
|
addItemToFixedCollection: (paramName: string) => {
|
||||||
|
this.getters.fixedCollectionParameter(paramName).getByTestId('fixed-collection-add').click();
|
||||||
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,9 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="fixed-collection-parameter" @keydown.stop>
|
<div
|
||||||
|
class="fixed-collection-parameter"
|
||||||
|
:data-test-id="`fixed-collection-${parameter.name}`"
|
||||||
|
@keydown.stop
|
||||||
|
>
|
||||||
<div v-if="getProperties.length === 0" class="no-items-exist">
|
<div v-if="getProperties.length === 0" class="no-items-exist">
|
||||||
<n8n-text size="small">{{
|
<n8n-text size="small">{{
|
||||||
$locale.baseText('fixedCollectionParameter.currentlyNoItemsExist')
|
$locale.baseText('fixedCollectionParameter.currentlyNoItemsExist')
|
||||||
|
@ -98,6 +102,7 @@
|
||||||
v-if="parameter.options && parameter.options.length === 1"
|
v-if="parameter.options && parameter.options.length === 1"
|
||||||
type="tertiary"
|
type="tertiary"
|
||||||
block
|
block
|
||||||
|
data-test-id="fixed-collection-add"
|
||||||
:label="getPlaceholderText"
|
:label="getPlaceholderText"
|
||||||
@click="optionSelected(parameter.options[0].name)"
|
@click="optionSelected(parameter.options[0].name)"
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -504,7 +504,12 @@ import TextEdit from '@/components/TextEdit.vue';
|
||||||
import { hasExpressionMapping, isValueExpression } from '@/utils/nodeTypesUtils';
|
import { hasExpressionMapping, isValueExpression } from '@/utils/nodeTypesUtils';
|
||||||
import { isResourceLocatorValue } from '@/utils/typeGuards';
|
import { isResourceLocatorValue } from '@/utils/typeGuards';
|
||||||
|
|
||||||
import { CUSTOM_API_CALL_KEY, HTML_NODE_TYPE, NODES_USING_CODE_NODE_EDITOR } from '@/constants';
|
import {
|
||||||
|
CORE_NODES_CATEGORY,
|
||||||
|
CUSTOM_API_CALL_KEY,
|
||||||
|
HTML_NODE_TYPE,
|
||||||
|
NODES_USING_CODE_NODE_EDITOR,
|
||||||
|
} from '@/constants';
|
||||||
|
|
||||||
import { useDebounce } from '@/composables/useDebounce';
|
import { useDebounce } from '@/composables/useDebounce';
|
||||||
import { useExternalHooks } from '@/composables/useExternalHooks';
|
import { useExternalHooks } from '@/composables/useExternalHooks';
|
||||||
|
@ -632,6 +637,15 @@ const dateTimePickerOptions = ref({
|
||||||
const isFocused = ref(false);
|
const isFocused = ref(false);
|
||||||
|
|
||||||
const displayValue = computed<string | number | boolean | null>(() => {
|
const displayValue = computed<string | number | boolean | null>(() => {
|
||||||
|
if (remoteParameterOptionsLoadingIssues.value) {
|
||||||
|
if (!nodeType.value || nodeType.value?.codex?.categories?.includes(CORE_NODES_CATEGORY)) {
|
||||||
|
return i18n.baseText('parameterInput.loadOptionsError');
|
||||||
|
}
|
||||||
|
return i18n.baseText('parameterInput.loadOptionsErrorService', {
|
||||||
|
interpolate: { service: nodeType.value.displayName },
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
if (remoteParameterOptionsLoading.value) {
|
if (remoteParameterOptionsLoading.value) {
|
||||||
// If it is loading options from server display
|
// If it is loading options from server display
|
||||||
// to user that the data is loading. If not it would
|
// to user that the data is loading. If not it would
|
||||||
|
@ -731,6 +745,9 @@ const dependentParametersValues = computed<string | null>(() => {
|
||||||
});
|
});
|
||||||
|
|
||||||
const node = computed(() => ndvStore.activeNode ?? undefined);
|
const node = computed(() => ndvStore.activeNode ?? undefined);
|
||||||
|
const nodeType = computed(
|
||||||
|
() => node.value && nodeTypesStore.getNodeType(node.value.type, node.value.typeVersion),
|
||||||
|
);
|
||||||
|
|
||||||
const displayTitle = computed<string>(() => {
|
const displayTitle = computed<string>(() => {
|
||||||
const interpolation = { interpolate: { shortPath: shortPath.value } };
|
const interpolation = { interpolate: { shortPath: shortPath.value } };
|
||||||
|
@ -1381,6 +1398,10 @@ watch(
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
|
watch(remoteParameterOptionsLoading, () => {
|
||||||
|
tempValue.value = displayValue.value as string;
|
||||||
|
});
|
||||||
|
|
||||||
onUpdated(async () => {
|
onUpdated(async () => {
|
||||||
await nextTick();
|
await nextTick();
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue