mirror of
https://github.com/Abdulazizzn/n8n-enterprise-unlocked.git
synced 2025-12-17 18:12:04 +00:00
117 lines
2.7 KiB
Vue
117 lines
2.7 KiB
Vue
<template>
|
|
<div ref="root" :class="$style.editor" @keydown.stop></div>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
import { history } from '@codemirror/commands';
|
|
import { Prec } from '@codemirror/state';
|
|
import { dropCursor, EditorView, keymap } from '@codemirror/view';
|
|
import { computed, onMounted, ref, watch } from 'vue';
|
|
|
|
import { expressionInputHandler } from '@/plugins/codemirror/inputHandlers/expression.inputHandler';
|
|
import { n8nAutocompletion, n8nLang } from '@/plugins/codemirror/n8nLang';
|
|
import { forceParse } from '@/utils/forceParse';
|
|
import { completionStatus } from '@codemirror/autocomplete';
|
|
import { inputTheme } from './theme';
|
|
|
|
import { useExpressionEditor } from '@/composables/useExpressionEditor';
|
|
import {
|
|
autocompleteKeyMap,
|
|
enterKeyMap,
|
|
historyKeyMap,
|
|
tabKeyMap,
|
|
} from '@/plugins/codemirror/keymap';
|
|
import { infoBoxTooltips } from '@/plugins/codemirror/tooltips/InfoBoxTooltip';
|
|
import type { Segment } from '@/types/expressions';
|
|
import { removeExpressionPrefix } from '@/utils/expressions';
|
|
import { mappingDropCursor } from '@/plugins/codemirror/dragAndDrop';
|
|
|
|
type Props = {
|
|
modelValue: string;
|
|
path: string;
|
|
isReadOnly?: boolean;
|
|
};
|
|
|
|
const props = withDefaults(defineProps<Props>(), {
|
|
isReadOnly: false,
|
|
});
|
|
|
|
const emit = defineEmits<{
|
|
change: [value: { value: string; segments: Segment[] }];
|
|
focus: [];
|
|
close: [];
|
|
}>();
|
|
|
|
const root = ref<HTMLElement>();
|
|
const extensions = computed(() => [
|
|
inputTheme(props.isReadOnly),
|
|
Prec.highest(
|
|
keymap.of([
|
|
...tabKeyMap(),
|
|
...historyKeyMap,
|
|
...enterKeyMap,
|
|
...autocompleteKeyMap,
|
|
{
|
|
any: (view, event) => {
|
|
if (event.key === 'Escape' && completionStatus(view.state) === null) {
|
|
event.stopPropagation();
|
|
emit('close');
|
|
}
|
|
|
|
return false;
|
|
},
|
|
},
|
|
]),
|
|
),
|
|
n8nLang(),
|
|
n8nAutocompletion(),
|
|
mappingDropCursor(),
|
|
dropCursor(),
|
|
history(),
|
|
expressionInputHandler(),
|
|
EditorView.lineWrapping,
|
|
EditorView.domEventHandlers({ scroll: forceParse }),
|
|
infoBoxTooltips(),
|
|
]);
|
|
const editorValue = ref<string>(removeExpressionPrefix(props.modelValue));
|
|
const { segments, readEditorValue, editor, hasFocus, focus } = useExpressionEditor({
|
|
editorRef: root,
|
|
editorValue,
|
|
extensions,
|
|
isReadOnly: props.isReadOnly,
|
|
autocompleteTelemetry: { enabled: true, parameterPath: props.path },
|
|
});
|
|
|
|
watch(
|
|
() => props.modelValue,
|
|
(newValue) => {
|
|
editorValue.value = removeExpressionPrefix(newValue);
|
|
},
|
|
);
|
|
|
|
watch(segments.display, (newSegments) => {
|
|
emit('change', {
|
|
value: '=' + readEditorValue(),
|
|
segments: newSegments,
|
|
});
|
|
});
|
|
|
|
watch(hasFocus, (focused) => {
|
|
if (focused) {
|
|
emit('focus');
|
|
}
|
|
});
|
|
|
|
onMounted(() => {
|
|
focus();
|
|
});
|
|
|
|
defineExpose({ editor });
|
|
</script>
|
|
|
|
<style lang="scss" module>
|
|
:global(.cm-content) {
|
|
border-radius: var(--border-radius-base);
|
|
}
|
|
</style>
|