Skip to content

Commit

Permalink
fix(editor): Fix hiding SQL query output when trying to select (#11649)
Browse files Browse the repository at this point in the history
  • Loading branch information
elsmr authored Nov 11, 2024
1 parent 4c41575 commit 4dbf2f4
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 4 deletions.
20 changes: 20 additions & 0 deletions packages/editor-ui/src/components/SQLEditor.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ async function focusEditor(container: Element) {
await waitFor(() => expect(container.querySelector('.cm-line')).toBeInTheDocument());
await userEvent.click(container.querySelector('.cm-line') as Element);
}

const nodes = [
{
id: '1',
Expand Down Expand Up @@ -172,4 +173,23 @@ describe('SqlEditor.vue', () => {
getByTestId(EXPRESSION_OUTPUT_TEST_ID).getElementsByClassName('cm-line').length,
);
});

it('should keep rendered output visible when clicking', async () => {
const { getByTestId, queryByTestId, container, baseElement } = renderComponent(SqlEditor, {
...DEFAULT_SETUP,
props: {
...DEFAULT_SETUP.props,
modelValue: 'SELECT * FROM users',
},
});

// Does not hide output when clicking inside the output
await focusEditor(container);
await userEvent.click(getByTestId(EXPRESSION_OUTPUT_TEST_ID));
await waitFor(() => expect(queryByTestId(EXPRESSION_OUTPUT_TEST_ID)).toBeInTheDocument());

// Does hide output when clicking outside the container
await userEvent.click(baseElement);
await waitFor(() => expect(queryByTestId(EXPRESSION_OUTPUT_TEST_ID)).not.toBeInTheDocument());
});
});
31 changes: 27 additions & 4 deletions packages/editor-ui/src/components/SqlEditor/SqlEditor.vue
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ import {
import { computed, onBeforeUnmount, onMounted, ref, toRaw, watch } from 'vue';
import { codeNodeEditorTheme } from '../CodeNodeEditor/theme';
import { dropInExpressionEditor, mappingDropCursor } from '@/plugins/codemirror/dragAndDrop';
import { onClickOutside } from '@vueuse/core';
const SQL_DIALECTS = {
StandardSQL,
Expand Down Expand Up @@ -68,7 +69,10 @@ const emit = defineEmits<{
'update:model-value': [value: string];
}>();
const sqlEditor = ref<HTMLElement>();
const container = ref<HTMLDivElement>();
const sqlEditor = ref<HTMLDivElement>();
const isFocused = ref(false);
const extensions = computed(() => {
const dialect = SQL_DIALECTS[props.dialect] ?? SQL_DIALECTS.StandardSQL;
function sqlWithN8nLanguageSupport() {
Expand Down Expand Up @@ -122,7 +126,7 @@ const {
editor,
segments: { all: segments },
readEditorValue,
hasFocus,
hasFocus: editorHasFocus,
} = useExpressionEditor({
editorRef: sqlEditor,
editorValue,
Expand All @@ -138,6 +142,12 @@ watch(
},
);
watch(editorHasFocus, (focus) => {
if (focus) {
isFocused.value = true;
}
});
watch(segments, () => {
emit('update:model-value', readEditorValue());
});
Expand All @@ -154,6 +164,19 @@ onBeforeUnmount(() => {
codeNodeEditorEventBus.off('highlightLine', highlightLine);
});
onClickOutside(container, (event) => onBlur(event));
function onBlur(event: FocusEvent | KeyboardEvent) {
if (
event?.target instanceof Element &&
Array.from(event.target.classList).some((_class) => _class.includes('resizer'))
) {
return; // prevent blur on resizing
}
isFocused.value = false;
}
function line(lineNumber: number): Line | null {
try {
return editor.value?.state.doc.line(lineNumber) ?? null;
Expand Down Expand Up @@ -189,7 +212,7 @@ async function onDrop(value: string, event: MouseEvent) {
</script>

<template>
<div :class="$style.sqlEditor">
<div ref="container" :class="$style.sqlEditor" @keydown.tab="onBlur">
<DraggableTarget type="mapping" :disabled="isReadOnly" @drop="onDrop">
<template #default="{ activeDrop, droppable }">
<div
Expand All @@ -207,7 +230,7 @@ async function onDrop(value: string, event: MouseEvent) {
v-if="!fullscreen"
:segments="segments"
:is-read-only="isReadOnly"
:visible="hasFocus"
:visible="isFocused"
/>
</div>
</template>
Expand Down

0 comments on commit 4dbf2f4

Please sign in to comment.