feat(editor): send selected SQL to AI panel

This commit is contained in:
gggaiitx authored and GitHub committed 2026-07-09 18:12:27 +08:00
1 parent f590a727a0
commit 482f7421be
13 files changed
+84 -5

No files matched your search

+34 -2
View File
@@ -61,6 +61,7 @@ import {
isResetZoomShortcut,
isRefreshDataShortcut,
isSaveShortcut,
isSendSelectionToAiShortcut,
isSwitchToNextTabShortcut,
isSwitchToPreviousTabShortcut,
isToggleSidebarShortcut,
@@ -101,6 +102,7 @@ const QuickOpenDialog = defineAsyncComponent(() => import("@/components/quick-op
type AiAssistantHandle = {
triggerAction: (action: AiAction, instruction?: string) => void;
setPrompt: (text: string) => void;
};
const { t } = useI18n();
@@ -475,12 +477,35 @@ function toggleSqlFilePanel() {
safeLocalStorageSet("dbx-sql-file-panel-open", String(showSqlFilePanel.value));
}
function invokeWhenAiReady(invoke: (handle: AiAssistantHandle) => void) {
if (aiAssistantRef.value) {
invoke(aiAssistantRef.value);
return;
}
// AiAssistant 是异步组件,首次打开面板时单个 nextTick 不足以等待挂载完成,
// 因此监听 ref,待其从 null 变为组件实例后再调用。
const stop = watch(aiAssistantRef, (handle) => {
if (handle) {
stop();
invoke(handle);
}
});
}
function fixWithAi(errorMessage: string) {
if (!showAiPanel.value) {
showAiPanel.value = true;
safeLocalStorageSet("dbx-ai-panel-open", "true");
}
nextTick(() => aiAssistantRef.value?.triggerAction("fix", errorMessage));
invokeWhenAiReady((handle) => handle.triggerAction("fix", errorMessage));
}
function sendSelectionToAi(sql: string) {
if (!showAiPanel.value) {
showAiPanel.value = true;
safeLocalStorageSet("dbx-ai-panel-open", "true");
}
invokeWhenAiReady((handle) => handle.setPrompt(sql));
}
function openAiPanel() {
@@ -508,7 +533,7 @@ function analyzeHistoryWithAi(entry: HistoryEntry) {
const title = t("history.aiAnalysisTab");
const tabId = queryStore.createTab(connectionId, database || "", title, "query");
queryStore.updateSql(tabId, entry.sql);
nextTick(() => aiAssistantRef.value?.triggerAction("explain", buildHistoryAiAnalysisPrompt(entry)));
invokeWhenAiReady((handle) => handle.triggerAction("explain", buildHistoryAiAnalysisPrompt(entry)));
}
function formatActiveSql() {
@@ -1505,6 +1530,12 @@ function handleKeydown(e: KeyboardEvent) {
requestActiveEditorExecute();
return;
}
if (activeTab.value?.mode === "query" && isSendSelectionToAiShortcut(e, shortcuts) && e.target instanceof Element && e.target.closest("[data-query-editor-root]")) {
e.preventDefault();
e.stopPropagation();
if (selectedSql.value.trim()) sendSelectionToAi(selectedSql.value);
return;
}
if (isModRShortcut(e) && e.target instanceof Element && contentAreaRef.value?.handleModRTarget(e.target)) {
e.preventDefault();
e.stopPropagation();
@@ -1847,6 +1878,7 @@ onUnmounted(() => {
:block-dangerous-redis-commands="blockDangerousRedisCommands"
@update:active-output-view="activeOutputView = $event"
@fix-with-ai="fixWithAi"
@send-selection-to-ai="sendSelectionToAi"
@execute="tryExecute($event)"
@cancel="cancelActiveExecution()"
@explain="tryExplain()"