fix(editor): Prevent cursor from jumping in the focus panel (no-changelog) (#17976)

This commit is contained in:
Daria
2025-08-05 10:22:41 +03:00
committed by GitHub
parent d0443dce11
commit 0fffb807ee

View File

@@ -24,7 +24,6 @@ import {
isResourceLocatorValue,
} from 'n8n-workflow';
import { useEnvironmentsStore } from '@/stores/environments.ee.store';
import { useDebounce } from '@/composables/useDebounce';
import { htmlEditorEventBus } from '@/event-bus';
import { hasFocusOnInput, isFocusableEl } from '@/utils/typesUtils';
import type { ResizeData, TargetNodeParameterContext } from '@/Interface';
@@ -58,7 +57,6 @@ const telemetry = useTelemetry();
const nodeSettingsParameters = useNodeSettingsParameters();
const environmentsStore = useEnvironmentsStore();
const deviceSupport = useDeviceSupport();
const { debounce } = useDebounce();
const styles = useStyles();
const focusedNodeParameter = computed(() => focusPanelStore.focusedNodeParameters[0]);
@@ -68,6 +66,8 @@ const resolvedParameter = computed(() =>
: undefined,
);
const inputValue = ref<string>('');
const focusPanelActive = computed(() => focusPanelStore.focusPanelActive);
const focusPanelWidth = computed(() => focusPanelStore.focusPanelWidth);
@@ -290,7 +290,10 @@ function onExecute() {
);
}
const valueChangedDebounced = debounce(valueChanged, { debounceTime: 0 });
function onInputChange(val: string) {
inputValue.value = val;
valueChanged(val);
}
// Wait for editor to mount before focusing
function focusWithDelay() {
@@ -333,6 +336,19 @@ watch(
{ immediate: true },
);
watch(
() => resolvedParameter.value,
(newValue) => {
if (newValue) {
const value = newValue.value;
if (typeof value === 'string' && value !== inputValue.value) {
inputValue.value = value;
}
}
},
{ immediate: true },
);
function onResize(event: ResizeData) {
focusPanelStore.updateWidth(event.width);
}
@@ -412,86 +428,86 @@ const onResizeThrottle = useThrottleFn(onResize, 10);
<ExpressionEditorModalInput
v-else-if="expressionModeEnabled"
ref="inputField"
:model-value="resolvedParameter.value"
v-model="inputValue"
:class="$style.editor"
:is-read-only="isReadOnly"
:path="resolvedParameter.parameterPath"
data-test-id="expression-modal-input"
:target-node-parameter-context="targetNodeParameterContext"
@change="valueChangedDebounced($event.value)"
@change="onInputChange($event.value)"
/>
<template v-else-if="['json', 'string'].includes(resolvedParameter.parameter.type)">
<CodeNodeEditor
v-if="editorType === 'codeNodeEditor'"
:id="resolvedParameter.parameterPath"
ref="inputField"
v-model="inputValue"
:class="$style.heightFull"
:mode="codeEditorMode"
:model-value="resolvedParameter.value"
:default-value="resolvedParameter.parameter.default"
:language="editorLanguage"
:is-read-only="isReadOnly"
:target-node-parameter-context="targetNodeParameterContext"
fill-parent
:disable-ask-ai="true"
@update:model-value="valueChangedDebounced" />
@update:model-value="onInputChange" />
<HtmlEditor
v-else-if="editorType === 'htmlEditor'"
ref="inputField"
:model-value="resolvedParameter.value"
v-model="inputValue"
:is-read-only="isReadOnly"
:rows="editorRows"
:disable-expression-coloring="!isHtmlNode"
:disable-expression-completions="!isHtmlNode"
fullscreen
:target-node-parameter-context="targetNodeParameterContext"
@update:model-value="valueChangedDebounced" />
@update:model-value="onInputChange" />
<CssEditor
v-else-if="editorType === 'cssEditor'"
ref="inputField"
:model-value="resolvedParameter.value"
v-model="inputValue"
:is-read-only="isReadOnly"
:rows="editorRows"
fullscreen
:target-node-parameter-context="targetNodeParameterContext"
@update:model-value="valueChangedDebounced" />
@update:model-value="onInputChange" />
<SqlEditor
v-else-if="editorType === 'sqlEditor'"
ref="inputField"
:model-value="resolvedParameter.value"
v-model="inputValue"
:dialect="getTypeOption('sqlDialect')"
:is-read-only="isReadOnly"
:rows="editorRows"
fullscreen
:target-node-parameter-context="targetNodeParameterContext"
@update:model-value="valueChangedDebounced" />
@update:model-value="onInputChange" />
<JsEditor
v-else-if="editorType === 'jsEditor'"
ref="inputField"
:model-value="resolvedParameter.value"
v-model="inputValue"
:is-read-only="isReadOnly"
:rows="editorRows"
:posthog-capture="shouldCaptureForPosthog"
fill-parent
@update:model-value="valueChangedDebounced" />
@update:model-value="onInputChange" />
<JsonEditor
v-else-if="resolvedParameter.parameter.type === 'json'"
ref="inputField"
:model-value="resolvedParameter.value"
v-model="inputValue"
:is-read-only="isReadOnly"
:rows="editorRows"
fullscreen
fill-parent
@update:model-value="valueChangedDebounced" />
@update:model-value="onInputChange" />
<N8nInput
v-else
ref="inputField"
:model-value="resolvedParameter.value"
v-model="inputValue"
:class="$style.editor"
:readonly="isReadOnly"
type="textarea"
resize="none"
@update:model-value="valueChangedDebounced"
@update:model-value="onInputChange"
></N8nInput
></template>
</div>