diff --git a/packages/editor-ui/src/components/ButtonParameter.test.ts b/packages/editor-ui/src/components/ButtonParameter/ButtonParameter.test.ts similarity index 99% rename from packages/editor-ui/src/components/ButtonParameter.test.ts rename to packages/editor-ui/src/components/ButtonParameter/ButtonParameter.test.ts index d018e23418..ba5070e335 100644 --- a/packages/editor-ui/src/components/ButtonParameter.test.ts +++ b/packages/editor-ui/src/components/ButtonParameter/ButtonParameter.test.ts @@ -45,6 +45,7 @@ describe('ButtonParameter', () => { vi.mocked(useNDVStore).mockReturnValue({ ndvInputData: [{}], activeNode: { name: 'TestNode', parameters: {} }, + isDraggableDragging: false, } as any); vi.mocked(useWorkflowsStore).mockReturnValue({ diff --git a/packages/editor-ui/src/components/ButtonParameter/ButtonParameter.vue b/packages/editor-ui/src/components/ButtonParameter/ButtonParameter.vue index 7bce766ea3..a321f3cc70 100644 --- a/packages/editor-ui/src/components/ButtonParameter/ButtonParameter.vue +++ b/packages/editor-ui/src/components/ButtonParameter/ButtonParameter.vue @@ -6,10 +6,18 @@ import { N8nButton, N8nInput, N8nTooltip } from 'n8n-design-system/components'; import { useI18n } from '@/composables/useI18n'; import { useToast } from '@/composables/useToast'; import { useNDVStore } from '@/stores/ndv.store'; -import { getParentNodes, generateCodeForAiTransform } from './utils'; +import { + getParentNodes, + generateCodeForAiTransform, + type TextareaRowData, + getUpdatedTextareaValue, + getTextareaCursorPosition, +} from './utils'; import { useTelemetry } from '@/composables/useTelemetry'; import { useUIStore } from '@/stores/ui.store'; +import { propertyNameFromExpression } from '../../utils/mappingUtils'; + const AI_TRANSFORM_CODE_GENERATED_FOR_PROMPT = 'codeGeneratedForPrompt'; const emit = defineEmits<{ @@ -29,6 +37,7 @@ const i18n = useI18n(); const isLoading = ref(false); const prompt = ref(props.value); const parentNodes = ref([]); +const textareaRowsData = ref(null); const hasExecutionData = computed(() => (useNDVStore().ndvInputData || []).length > 0); const hasInputField = computed(() => props.parameter.typeOptions?.buttonConfig?.hasInputField); @@ -159,6 +168,37 @@ function useDarkBackdrop(): string { onMounted(() => { parentNodes.value = getParentNodes(); }); + +function cleanTextareaRowsData() { + textareaRowsData.value = null; +} + +async function onDrop(value: string, event: MouseEvent) { + value = propertyNameFromExpression(value); + + prompt.value = getUpdatedTextareaValue(event, textareaRowsData.value, value); + + emit('valueChanged', { + name: getPath(props.parameter.name), + value: prompt.value, + }); +} + +async function updateCursorPositionOnMouseMove(event: MouseEvent, activeDrop: boolean) { + if (!activeDrop) return; + + const textarea = event.target as HTMLTextAreaElement; + + const position = getTextareaCursorPosition( + textarea, + textareaRowsData.value, + event.clientX, + event.clientY, + ); + + textarea.focus(); + textarea.setSelectionRange(position, position); +}