From 2c252b0b2d5282f4a87bce76f93c4c02dd8ff5e3 Mon Sep 17 00:00:00 2001 From: Michael Kret <88898367+michael-radency@users.noreply.github.com> Date: Wed, 27 Nov 2024 12:42:55 +0200 Subject: [PATCH] feat(AI Transform Node): Support for drag and drop (#11276) --- .../ButtonParameter.test.ts | 1 + .../ButtonParameter/ButtonParameter.vue | 80 +++++++-- .../src/components/ButtonParameter/utils.ts | 166 ++++++++++++++++++ 3 files changed, 235 insertions(+), 12 deletions(-) rename packages/editor-ui/src/components/{ => ButtonParameter}/ButtonParameter.test.ts (99%) 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); +}