fix(editor): Prevent search dialog from covering inline expression parameters (#19238)

This commit is contained in:
Charlie Kolb
2025-09-05 13:59:38 +02:00
committed by GitHub
parent 9a9ef5cd61
commit 0d7f9ae182
2 changed files with 19 additions and 0 deletions

View File

@@ -71,6 +71,7 @@ const {
editorRef: root, editorRef: root,
editorValue, editorValue,
extensions, extensions,
disableSearchDialog: true,
isReadOnly: computed(() => props.isReadOnly), isReadOnly: computed(() => props.isReadOnly),
autocompleteTelemetry: { enabled: true, parameterPath: props.path }, autocompleteTelemetry: { enabled: true, parameterPath: props.path },
additionalData: props.additionalData, additionalData: props.additionalData,

View File

@@ -6,6 +6,7 @@ import {
ref, ref,
toRef, toRef,
toValue, toValue,
unref,
watch, watch,
watchEffect, watchEffect,
type MaybeRefOrGetter, type MaybeRefOrGetter,
@@ -41,6 +42,7 @@ import { useWorkflowsStore } from '../stores/workflows.store';
import { useAutocompleteTelemetry } from './useAutocompleteTelemetry'; import { useAutocompleteTelemetry } from './useAutocompleteTelemetry';
import { ignoreUpdateAnnotation } from '../utils/forceParse'; import { ignoreUpdateAnnotation } from '../utils/forceParse';
import { TARGET_NODE_PARAMETER_FACET } from '@/plugins/codemirror/completions/constants'; import { TARGET_NODE_PARAMETER_FACET } from '@/plugins/codemirror/completions/constants';
import { useDeviceSupport } from '@n8n/composables/useDeviceSupport';
export const useExpressionEditor = ({ export const useExpressionEditor = ({
editorRef, editorRef,
@@ -51,6 +53,7 @@ export const useExpressionEditor = ({
skipSegments = [], skipSegments = [],
autocompleteTelemetry, autocompleteTelemetry,
isReadOnly = false, isReadOnly = false,
disableSearchDialog = false,
onChange = () => {}, onChange = () => {},
}: { }: {
editorRef: MaybeRefOrGetter<HTMLElement | undefined>; editorRef: MaybeRefOrGetter<HTMLElement | undefined>;
@@ -61,11 +64,13 @@ export const useExpressionEditor = ({
skipSegments?: MaybeRefOrGetter<string[]>; skipSegments?: MaybeRefOrGetter<string[]>;
autocompleteTelemetry?: MaybeRefOrGetter<{ enabled: true; parameterPath: string }>; autocompleteTelemetry?: MaybeRefOrGetter<{ enabled: true; parameterPath: string }>;
isReadOnly?: MaybeRefOrGetter<boolean>; isReadOnly?: MaybeRefOrGetter<boolean>;
disableSearchDialog?: MaybeRefOrGetter<boolean>;
onChange?: (viewUpdate: ViewUpdate) => void; onChange?: (viewUpdate: ViewUpdate) => void;
}) => { }) => {
const ndvStore = useNDVStore(); const ndvStore = useNDVStore();
const workflowsStore = useWorkflowsStore(); const workflowsStore = useWorkflowsStore();
const workflowHelpers = useWorkflowHelpers(); const workflowHelpers = useWorkflowHelpers();
const { isMacOs } = useDeviceSupport();
const i18n = useI18n(); const i18n = useI18n();
const editor = ref<EditorView>(); const editor = ref<EditorView>();
const hasFocus = ref(false); const hasFocus = ref(false);
@@ -198,6 +203,17 @@ export const useExpressionEditor = ({
dragging.value = false; dragging.value = false;
} }
function onKeyDown(e: KeyboardEvent) {
if (
unref(disableSearchDialog) &&
// Avoid blocking editor shortcuts like `ctrl+f` to go to next character on mac
((isMacOs && e.metaKey) || (!isMacOs && e.ctrlKey)) &&
e.key === 'f'
) {
e.preventDefault();
}
}
watch(toRef(editorRef), () => { watch(toRef(editorRef), () => {
const parent = toValue(editorRef); const parent = toValue(editorRef);
@@ -237,6 +253,8 @@ export const useExpressionEditor = ({
editor.value.destroy(); editor.value.destroy();
} }
editor.value = new EditorView({ parent, state }); editor.value = new EditorView({ parent, state });
// Capture is needed here to prevent the browser search window to open in the inline editor
editor.value.dom.addEventListener('keydown', onKeyDown, { capture: true });
debouncedUpdateSegments(); debouncedUpdateSegments();
}); });