mirror of
https://github.com/Abdulazizzn/n8n-enterprise-unlocked.git
synced 2025-12-19 11:01:15 +00:00
fix(editor): Make deleting Call n8n Workflow Tool fromAI workflow input descriptions work (#15459)
This commit is contained in:
@@ -31,6 +31,8 @@ describe('N8nSelectableList', () => {
|
|||||||
await fireEvent.click(wrapper.getByTestId('selectable-list-remove-slot-propA'));
|
await fireEvent.click(wrapper.getByTestId('selectable-list-remove-slot-propA'));
|
||||||
|
|
||||||
expect(wrapper.queryByTestId('selectable-list-slot-propA')).not.toBeInTheDocument();
|
expect(wrapper.queryByTestId('selectable-list-slot-propA')).not.toBeInTheDocument();
|
||||||
|
expect(wrapper.emitted('removeItem')).toHaveLength(1);
|
||||||
|
expect(wrapper.emitted('removeItem')[0]).toEqual(['propA']);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('renders multiple elements with some pre-selected', () => {
|
it('renders multiple elements with some pre-selected', () => {
|
||||||
|
|||||||
@@ -12,6 +12,10 @@ defineSlots<{
|
|||||||
displayItem: (props: Item) => unknown;
|
displayItem: (props: Item) => unknown;
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
|
const emit = defineEmits<{
|
||||||
|
removeItem: [name: string];
|
||||||
|
}>();
|
||||||
|
|
||||||
type SelectableListProps = {
|
type SelectableListProps = {
|
||||||
inputs: Item[];
|
inputs: Item[];
|
||||||
disabled?: boolean;
|
disabled?: boolean;
|
||||||
@@ -50,6 +54,7 @@ function addToSelectedItems(name: string) {
|
|||||||
|
|
||||||
function removeFromSelectedItems(name: string) {
|
function removeFromSelectedItems(name: string) {
|
||||||
delete selectedItems.value[name];
|
delete selectedItems.value[name];
|
||||||
|
emit('removeItem', name);
|
||||||
}
|
}
|
||||||
|
|
||||||
function itemComparator(a: Item, b: Item) {
|
function itemComparator(a: Item, b: Item) {
|
||||||
|
|||||||
@@ -0,0 +1,165 @@
|
|||||||
|
import userEvent from '@testing-library/user-event';
|
||||||
|
import { createComponentRenderer } from '@/__tests__/render';
|
||||||
|
import ParameterOverrideSelectableList from './ParameterOverrideSelectableList.vue';
|
||||||
|
import { createTestingPinia } from '@pinia/testing';
|
||||||
|
import { ref } from 'vue';
|
||||||
|
import { createAppModals } from '@/__tests__/utils';
|
||||||
|
import { STORES } from '@n8n/stores';
|
||||||
|
|
||||||
|
vi.mock('vue-router', () => {
|
||||||
|
return {
|
||||||
|
useRouter: () => ({
|
||||||
|
push: vi.fn(),
|
||||||
|
resolve: vi.fn().mockReturnValue({ href: 'https://test.com' }),
|
||||||
|
}),
|
||||||
|
useRoute: () => ({}),
|
||||||
|
RouterLink: vi.fn(),
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
createAppModals();
|
||||||
|
});
|
||||||
|
|
||||||
|
const renderComponent = createComponentRenderer(ParameterOverrideSelectableList, {
|
||||||
|
pinia: createTestingPinia({
|
||||||
|
initialState: {
|
||||||
|
[STORES.SETTINGS]: {
|
||||||
|
settings: {
|
||||||
|
enterprise: {
|
||||||
|
externalSecrets: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('ParameterOverrideSelectableList', () => {
|
||||||
|
it('should render the component', () => {
|
||||||
|
const model = ref({
|
||||||
|
type: 'fromAI',
|
||||||
|
extraProps: {
|
||||||
|
description: {
|
||||||
|
initialValue: 'Test',
|
||||||
|
type: 'string',
|
||||||
|
typeOptions: { rows: 2 },
|
||||||
|
tooltip: '',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
extraPropValues: { description: 'Test description' },
|
||||||
|
});
|
||||||
|
const update = vi.fn((v) => (model.value = v));
|
||||||
|
|
||||||
|
const { getByTestId } = renderComponent({
|
||||||
|
props: {
|
||||||
|
isReadOnly: false,
|
||||||
|
parameter: {
|
||||||
|
displayName: 'test',
|
||||||
|
name: 'value["test"]',
|
||||||
|
type: 'string',
|
||||||
|
default: '',
|
||||||
|
required: false,
|
||||||
|
description: '',
|
||||||
|
readOnly: false,
|
||||||
|
},
|
||||||
|
path: 'parameters.workflowInputs.value["test"]',
|
||||||
|
modelValue: model.value,
|
||||||
|
'onUpdate:modelValue': update,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(getByTestId('parameter-input-field')).toBeInTheDocument();
|
||||||
|
expect(getByTestId('selectable-list-remove-slot-description')).toBeInTheDocument();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should update extra prop value when input changes', async () => {
|
||||||
|
const model = ref({
|
||||||
|
type: 'fromAI',
|
||||||
|
extraProps: {
|
||||||
|
description: {
|
||||||
|
initialValue: 'Test',
|
||||||
|
type: 'string',
|
||||||
|
typeOptions: { rows: 2 },
|
||||||
|
tooltip: '',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
extraPropValues: { description: 'Test description' },
|
||||||
|
});
|
||||||
|
const update = vi.fn((v) => (model.value = v));
|
||||||
|
|
||||||
|
const { getByTestId, emitted } = renderComponent({
|
||||||
|
props: {
|
||||||
|
isReadOnly: false,
|
||||||
|
parameter: {
|
||||||
|
displayName: 'test',
|
||||||
|
name: 'value["test"]',
|
||||||
|
type: 'string',
|
||||||
|
default: '',
|
||||||
|
required: false,
|
||||||
|
description: '',
|
||||||
|
readOnly: false,
|
||||||
|
},
|
||||||
|
path: 'parameters.workflowInputs.value["test"]',
|
||||||
|
modelValue: model.value,
|
||||||
|
'onUpdate:modelValue': update,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
await userEvent.type(getByTestId('parameter-input-field'), '2');
|
||||||
|
expect(model.value.extraPropValues.description).toBe('Test description2');
|
||||||
|
expect(emitted('update')).toHaveLength(1);
|
||||||
|
expect(emitted('update')[0]).toEqual([
|
||||||
|
{
|
||||||
|
name: 'parameters.workflowInputs.value["test"]',
|
||||||
|
value:
|
||||||
|
"={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('test', `Test description2`, 'string') }}",
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should reset extra prop back to default when removed', async () => {
|
||||||
|
const model = ref({
|
||||||
|
type: 'fromAI',
|
||||||
|
extraProps: {
|
||||||
|
description: {
|
||||||
|
initialValue: '',
|
||||||
|
type: 'string',
|
||||||
|
typeOptions: { rows: 2 },
|
||||||
|
tooltip: '',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
extraPropValues: { description: 'Test description' },
|
||||||
|
});
|
||||||
|
const update = vi.fn((v) => (model.value = v));
|
||||||
|
|
||||||
|
const { getByTestId, emitted } = renderComponent({
|
||||||
|
props: {
|
||||||
|
isReadOnly: false,
|
||||||
|
parameter: {
|
||||||
|
displayName: 'test',
|
||||||
|
name: 'value["test"]',
|
||||||
|
type: 'string',
|
||||||
|
default: '',
|
||||||
|
required: false,
|
||||||
|
description: '',
|
||||||
|
readOnly: false,
|
||||||
|
},
|
||||||
|
path: 'parameters.workflowInputs.value["test"]',
|
||||||
|
modelValue: model.value,
|
||||||
|
'onUpdate:modelValue': update,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(model.value.extraPropValues.description).toBeDefined();
|
||||||
|
await userEvent.click(getByTestId('selectable-list-remove-slot-description'));
|
||||||
|
expect(model.value.extraPropValues.description).toBeUndefined();
|
||||||
|
expect(emitted('update')).toHaveLength(1);
|
||||||
|
expect(emitted('update')[0]).toEqual([
|
||||||
|
{
|
||||||
|
name: 'parameters.workflowInputs.value["test"]',
|
||||||
|
value: "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('test', ``, 'string') }}",
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -36,6 +36,14 @@ const emit = defineEmits<{
|
|||||||
function valueChanged(parameterData: IUpdateInformation) {
|
function valueChanged(parameterData: IUpdateInformation) {
|
||||||
emit('update', parameterData);
|
emit('update', parameterData);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function onExtraPropValueRemove(name: string) {
|
||||||
|
delete parameterOverride.value.extraPropValues[name];
|
||||||
|
valueChanged({
|
||||||
|
name: props.path,
|
||||||
|
value: buildValueFromOverride(parameterOverride.value, props, true),
|
||||||
|
});
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
@@ -44,6 +52,7 @@ function valueChanged(parameterData: IUpdateInformation) {
|
|||||||
class="mt-2xs"
|
class="mt-2xs"
|
||||||
:inputs="inputs"
|
:inputs="inputs"
|
||||||
:disabled="isReadOnly"
|
:disabled="isReadOnly"
|
||||||
|
@remove-item="onExtraPropValueRemove"
|
||||||
>
|
>
|
||||||
<template #displayItem="{ name, tooltip, initialValue, type, typeOptions }">
|
<template #displayItem="{ name, tooltip, initialValue, type, typeOptions }">
|
||||||
<ParameterInputFull
|
<ParameterInputFull
|
||||||
|
|||||||
Reference in New Issue
Block a user