diff --git a/frontend/src/components/SqlEditor.tsx b/frontend/src/components/SqlEditor.tsx index 21ee80d..88a0819 100644 --- a/frontend/src/components/SqlEditor.tsx +++ b/frontend/src/components/SqlEditor.tsx @@ -1,4 +1,4 @@ -import { useRef } from 'react'; +import { useRef, useEffect } from 'react'; import Editor, { Monaco, loader } from '@monaco-editor/react'; import { databasesApi } from '@/services/api'; import * as monacoEditor from 'monaco-editor'; @@ -46,14 +46,29 @@ const getCachedTables = async (databaseId: string): Promise => { } }; +// Global flag to ensure we only register the completion provider once +let completionProviderRegistered = false; +let currentDatabaseId: string | undefined; + export default function SqlEditor({ value, onChange, databaseId, height = '400px' }: SqlEditorProps) { const editorRef = useRef(null); const monacoRef = useRef(null); + // Update current database ID when it changes + useEffect(() => { + currentDatabaseId = databaseId; + }, [databaseId]); + const handleEditorDidMount = (editor: any, monaco: Monaco) => { editorRef.current = editor; monacoRef.current = monaco; + // Register completion provider only once + if (completionProviderRegistered) { + return; + } + completionProviderRegistered = true; + // Configure SQL language features monaco.languages.registerCompletionItemProvider('sql', { provideCompletionItems: async (model, position) => { @@ -91,8 +106,8 @@ export default function SqlEditor({ value, onChange, databaseId, height = '400px ]; // Fetch table names from database if databaseId is provided (with caching) - if (databaseId) { - const tables = await getCachedTables(databaseId); + if (currentDatabaseId) { + const tables = await getCachedTables(currentDatabaseId); const tableSuggestions = tables.map(table => ({ label: table, kind: monaco.languages.CompletionItemKind.Class,