mirror of
https://github.com/Abdulazizzn/n8n-enterprise-unlocked.git
synced 2025-12-17 18:12:04 +00:00
fix(editor): Prevent cursor from jumping in the focus panel (no-changelog) (#17976)
This commit is contained in:
@@ -24,7 +24,6 @@ import {
|
|||||||
isResourceLocatorValue,
|
isResourceLocatorValue,
|
||||||
} from 'n8n-workflow';
|
} from 'n8n-workflow';
|
||||||
import { useEnvironmentsStore } from '@/stores/environments.ee.store';
|
import { useEnvironmentsStore } from '@/stores/environments.ee.store';
|
||||||
import { useDebounce } from '@/composables/useDebounce';
|
|
||||||
import { htmlEditorEventBus } from '@/event-bus';
|
import { htmlEditorEventBus } from '@/event-bus';
|
||||||
import { hasFocusOnInput, isFocusableEl } from '@/utils/typesUtils';
|
import { hasFocusOnInput, isFocusableEl } from '@/utils/typesUtils';
|
||||||
import type { ResizeData, TargetNodeParameterContext } from '@/Interface';
|
import type { ResizeData, TargetNodeParameterContext } from '@/Interface';
|
||||||
@@ -58,7 +57,6 @@ const telemetry = useTelemetry();
|
|||||||
const nodeSettingsParameters = useNodeSettingsParameters();
|
const nodeSettingsParameters = useNodeSettingsParameters();
|
||||||
const environmentsStore = useEnvironmentsStore();
|
const environmentsStore = useEnvironmentsStore();
|
||||||
const deviceSupport = useDeviceSupport();
|
const deviceSupport = useDeviceSupport();
|
||||||
const { debounce } = useDebounce();
|
|
||||||
const styles = useStyles();
|
const styles = useStyles();
|
||||||
|
|
||||||
const focusedNodeParameter = computed(() => focusPanelStore.focusedNodeParameters[0]);
|
const focusedNodeParameter = computed(() => focusPanelStore.focusedNodeParameters[0]);
|
||||||
@@ -68,6 +66,8 @@ const resolvedParameter = computed(() =>
|
|||||||
: undefined,
|
: undefined,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const inputValue = ref<string>('');
|
||||||
|
|
||||||
const focusPanelActive = computed(() => focusPanelStore.focusPanelActive);
|
const focusPanelActive = computed(() => focusPanelStore.focusPanelActive);
|
||||||
const focusPanelWidth = computed(() => focusPanelStore.focusPanelWidth);
|
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
|
// Wait for editor to mount before focusing
|
||||||
function focusWithDelay() {
|
function focusWithDelay() {
|
||||||
@@ -333,6 +336,19 @@ watch(
|
|||||||
{ immediate: true },
|
{ 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) {
|
function onResize(event: ResizeData) {
|
||||||
focusPanelStore.updateWidth(event.width);
|
focusPanelStore.updateWidth(event.width);
|
||||||
}
|
}
|
||||||
@@ -412,86 +428,86 @@ const onResizeThrottle = useThrottleFn(onResize, 10);
|
|||||||
<ExpressionEditorModalInput
|
<ExpressionEditorModalInput
|
||||||
v-else-if="expressionModeEnabled"
|
v-else-if="expressionModeEnabled"
|
||||||
ref="inputField"
|
ref="inputField"
|
||||||
:model-value="resolvedParameter.value"
|
v-model="inputValue"
|
||||||
:class="$style.editor"
|
:class="$style.editor"
|
||||||
:is-read-only="isReadOnly"
|
:is-read-only="isReadOnly"
|
||||||
:path="resolvedParameter.parameterPath"
|
:path="resolvedParameter.parameterPath"
|
||||||
data-test-id="expression-modal-input"
|
data-test-id="expression-modal-input"
|
||||||
:target-node-parameter-context="targetNodeParameterContext"
|
:target-node-parameter-context="targetNodeParameterContext"
|
||||||
@change="valueChangedDebounced($event.value)"
|
@change="onInputChange($event.value)"
|
||||||
/>
|
/>
|
||||||
<template v-else-if="['json', 'string'].includes(resolvedParameter.parameter.type)">
|
<template v-else-if="['json', 'string'].includes(resolvedParameter.parameter.type)">
|
||||||
<CodeNodeEditor
|
<CodeNodeEditor
|
||||||
v-if="editorType === 'codeNodeEditor'"
|
v-if="editorType === 'codeNodeEditor'"
|
||||||
:id="resolvedParameter.parameterPath"
|
:id="resolvedParameter.parameterPath"
|
||||||
ref="inputField"
|
ref="inputField"
|
||||||
|
v-model="inputValue"
|
||||||
:class="$style.heightFull"
|
:class="$style.heightFull"
|
||||||
:mode="codeEditorMode"
|
:mode="codeEditorMode"
|
||||||
:model-value="resolvedParameter.value"
|
|
||||||
:default-value="resolvedParameter.parameter.default"
|
:default-value="resolvedParameter.parameter.default"
|
||||||
:language="editorLanguage"
|
:language="editorLanguage"
|
||||||
:is-read-only="isReadOnly"
|
:is-read-only="isReadOnly"
|
||||||
:target-node-parameter-context="targetNodeParameterContext"
|
:target-node-parameter-context="targetNodeParameterContext"
|
||||||
fill-parent
|
fill-parent
|
||||||
:disable-ask-ai="true"
|
:disable-ask-ai="true"
|
||||||
@update:model-value="valueChangedDebounced" />
|
@update:model-value="onInputChange" />
|
||||||
<HtmlEditor
|
<HtmlEditor
|
||||||
v-else-if="editorType === 'htmlEditor'"
|
v-else-if="editorType === 'htmlEditor'"
|
||||||
ref="inputField"
|
ref="inputField"
|
||||||
:model-value="resolvedParameter.value"
|
v-model="inputValue"
|
||||||
:is-read-only="isReadOnly"
|
:is-read-only="isReadOnly"
|
||||||
:rows="editorRows"
|
:rows="editorRows"
|
||||||
:disable-expression-coloring="!isHtmlNode"
|
:disable-expression-coloring="!isHtmlNode"
|
||||||
:disable-expression-completions="!isHtmlNode"
|
:disable-expression-completions="!isHtmlNode"
|
||||||
fullscreen
|
fullscreen
|
||||||
:target-node-parameter-context="targetNodeParameterContext"
|
:target-node-parameter-context="targetNodeParameterContext"
|
||||||
@update:model-value="valueChangedDebounced" />
|
@update:model-value="onInputChange" />
|
||||||
<CssEditor
|
<CssEditor
|
||||||
v-else-if="editorType === 'cssEditor'"
|
v-else-if="editorType === 'cssEditor'"
|
||||||
ref="inputField"
|
ref="inputField"
|
||||||
:model-value="resolvedParameter.value"
|
v-model="inputValue"
|
||||||
:is-read-only="isReadOnly"
|
:is-read-only="isReadOnly"
|
||||||
:rows="editorRows"
|
:rows="editorRows"
|
||||||
fullscreen
|
fullscreen
|
||||||
:target-node-parameter-context="targetNodeParameterContext"
|
:target-node-parameter-context="targetNodeParameterContext"
|
||||||
@update:model-value="valueChangedDebounced" />
|
@update:model-value="onInputChange" />
|
||||||
<SqlEditor
|
<SqlEditor
|
||||||
v-else-if="editorType === 'sqlEditor'"
|
v-else-if="editorType === 'sqlEditor'"
|
||||||
ref="inputField"
|
ref="inputField"
|
||||||
:model-value="resolvedParameter.value"
|
v-model="inputValue"
|
||||||
:dialect="getTypeOption('sqlDialect')"
|
:dialect="getTypeOption('sqlDialect')"
|
||||||
:is-read-only="isReadOnly"
|
:is-read-only="isReadOnly"
|
||||||
:rows="editorRows"
|
:rows="editorRows"
|
||||||
fullscreen
|
fullscreen
|
||||||
:target-node-parameter-context="targetNodeParameterContext"
|
:target-node-parameter-context="targetNodeParameterContext"
|
||||||
@update:model-value="valueChangedDebounced" />
|
@update:model-value="onInputChange" />
|
||||||
<JsEditor
|
<JsEditor
|
||||||
v-else-if="editorType === 'jsEditor'"
|
v-else-if="editorType === 'jsEditor'"
|
||||||
ref="inputField"
|
ref="inputField"
|
||||||
:model-value="resolvedParameter.value"
|
v-model="inputValue"
|
||||||
:is-read-only="isReadOnly"
|
:is-read-only="isReadOnly"
|
||||||
:rows="editorRows"
|
:rows="editorRows"
|
||||||
:posthog-capture="shouldCaptureForPosthog"
|
:posthog-capture="shouldCaptureForPosthog"
|
||||||
fill-parent
|
fill-parent
|
||||||
@update:model-value="valueChangedDebounced" />
|
@update:model-value="onInputChange" />
|
||||||
<JsonEditor
|
<JsonEditor
|
||||||
v-else-if="resolvedParameter.parameter.type === 'json'"
|
v-else-if="resolvedParameter.parameter.type === 'json'"
|
||||||
ref="inputField"
|
ref="inputField"
|
||||||
:model-value="resolvedParameter.value"
|
v-model="inputValue"
|
||||||
:is-read-only="isReadOnly"
|
:is-read-only="isReadOnly"
|
||||||
:rows="editorRows"
|
:rows="editorRows"
|
||||||
fullscreen
|
fullscreen
|
||||||
fill-parent
|
fill-parent
|
||||||
@update:model-value="valueChangedDebounced" />
|
@update:model-value="onInputChange" />
|
||||||
<N8nInput
|
<N8nInput
|
||||||
v-else
|
v-else
|
||||||
ref="inputField"
|
ref="inputField"
|
||||||
:model-value="resolvedParameter.value"
|
v-model="inputValue"
|
||||||
:class="$style.editor"
|
:class="$style.editor"
|
||||||
:readonly="isReadOnly"
|
:readonly="isReadOnly"
|
||||||
type="textarea"
|
type="textarea"
|
||||||
resize="none"
|
resize="none"
|
||||||
@update:model-value="valueChangedDebounced"
|
@update:model-value="onInputChange"
|
||||||
></N8nInput
|
></N8nInput
|
||||||
></template>
|
></template>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user