mirror of
https://github.com/t8y2/dbx.git
synced 2026-10-19 16:16:45 +00:00
fix(sql): route shortcut new query to selected sidebar connection
This commit is contained in:
@@ -88,7 +88,7 @@ import { OBJECT_BROWSER_SEARCH_FOCUS_EVENT, objectBrowserSearchFocusTabId } from
|
||||
import { parseRecentConnectionIds, rankRecentConnections, RECENT_CONNECTION_IDS_STORAGE_KEY, recordRecentConnection } from "@/lib/connection/recentConnections";
|
||||
import { resolveDefaultDatabase } from "@/lib/database/defaultDatabase";
|
||||
import { normalizeSqliteNamespace } from "@/lib/database/sqliteNamespace";
|
||||
import { findTreeNodeById, resolveNewQueryTarget, resolveNewQueryInitialSql } from "@/lib/sql/newQueryContext";
|
||||
import { findTreeNodeById, resolveNewQueryTarget, resolveNewQueryInitialSql, type NewQueryContextSource } from "@/lib/sql/newQueryContext";
|
||||
import { isSqlObjectNavigationRoutineType, normalizeOracleNavigationTarget, sqlObjectNavigationSourceKind, sqlObjectNavigationSourceName, sqlObjectNavigationSourceSchema, sqlObjectNavigationTableType, type SqlObjectNavigationTarget } from "@/lib/sql/sqlNavigation";
|
||||
import { buildEditableObjectSource, buildExecutableObjectSourceStatements, executeObjectSourceSave } from "@/lib/table/objectSourceEditor";
|
||||
import { loadEditableObjectSourceForEditor } from "@/lib/table/objectSourceLoad";
|
||||
@@ -1112,8 +1112,9 @@ provide(GROUP_TAB_BAR_PORTAL, createGroupTabBarPortal(isSpecialPageActive));
|
||||
provide(EDITOR_TOOLBAR_ACTIONS, {
|
||||
canNewQuery: canCreateNewQuery,
|
||||
newQuery: (groupId: string) => {
|
||||
lastFocusedSidebarSurface.value = false;
|
||||
queryStore.focusGroup(groupId);
|
||||
void newQuery();
|
||||
void newQuery({ preferredSource: "tab" });
|
||||
},
|
||||
explainMode,
|
||||
blockDangerousRedisCommands,
|
||||
@@ -1305,6 +1306,7 @@ function activateMainContentSurface(surface: MainContentSurface) {
|
||||
settingsStore.settingsPageActive = surface === "settings";
|
||||
driverStoreActive.value = surface === "driverStore";
|
||||
pluginCenterActive.value = surface === "pluginCenter";
|
||||
lastFocusedSidebarSurface.value = false;
|
||||
}
|
||||
|
||||
watch(
|
||||
@@ -3092,7 +3094,11 @@ function openConnectionSettings(connectionId: string, initialTab: ConfigTab = "c
|
||||
showConnectionDialog.value = true;
|
||||
}
|
||||
|
||||
async function newQuery() {
|
||||
interface NewQueryOptions {
|
||||
preferredSource?: NewQueryContextSource;
|
||||
}
|
||||
|
||||
async function newQuery(options: NewQueryOptions = {}) {
|
||||
const sqlConnections = connectionStore.connections.filter((connection) => quickConnectionOpenTarget(connection).kind === "query" && supportsGenericNewQuery(connection));
|
||||
const connectedSqlConnectionIds = new Set(sqlConnections.filter((connection) => connectionStore.connectedIds.has(connection.id)).map((connection) => connection.id));
|
||||
let target = resolveNewQueryTarget({
|
||||
@@ -3101,6 +3107,7 @@ async function newQuery() {
|
||||
activeConnectionId: connectionStore.activeConnectionId,
|
||||
connections: connectionStore.connections,
|
||||
connectedSqlConnectionIds,
|
||||
preferredSource: options.preferredSource,
|
||||
});
|
||||
if (!target) {
|
||||
// No active editor/sidebar choice and no unique online SQL connection:
|
||||
@@ -3157,6 +3164,7 @@ async function newQuery() {
|
||||
const initialSql = resolveNewQueryInitialSql({
|
||||
activeTab: activeTab.value,
|
||||
selectedTreeNode: findTreeNodeById(connectionStore.treeNodes, connectionStore.selectedTreeNodeId),
|
||||
preferredSource: options.preferredSource,
|
||||
prefillEnabled: settingsStore.editorSettings.prefillNewQueryWithSelect,
|
||||
targetConnectionId: target.connectionId,
|
||||
targetDatabase: target.database,
|
||||
@@ -4178,6 +4186,10 @@ function rememberSidebarSearchSurface() {
|
||||
lastFocusedSidebarSurface.value = true;
|
||||
}
|
||||
|
||||
function rememberEditorContentSurface() {
|
||||
lastFocusedSidebarSurface.value = false;
|
||||
}
|
||||
|
||||
function setPluginWorkbenchTabRef(tabId: string, element: unknown) {
|
||||
if (element && typeof element === "object" && "refresh" in element && typeof element.refresh === "function") {
|
||||
pluginWorkbenchTabRefs.set(tabId, element as PluginWorkbenchTabHandle);
|
||||
@@ -4316,7 +4328,10 @@ async function handleKeydown(e: KeyboardEvent) {
|
||||
if (isNewQueryShortcut(e, shortcuts)) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
void newQuery();
|
||||
const target = e.target instanceof Element ? e.target : null;
|
||||
const targetIsDocument = !target || target === document.body || target === document.documentElement;
|
||||
const sidebarFocused = target?.closest("[data-app-sidebar]") || (targetIsDocument && lastFocusedSidebarSurface.value);
|
||||
void newQuery({ preferredSource: sidebarFocused ? "sidebar" : undefined });
|
||||
return;
|
||||
}
|
||||
if (isToggleSidebarShortcut(e, shortcuts)) {
|
||||
@@ -4886,6 +4901,7 @@ onUnmounted(() => {
|
||||
data-editor-content
|
||||
v-show="isSpecialPageActive || (!isAiPanelMaximized && !isHistoryPanelMaximized) || isZenMode"
|
||||
:class="isDetachedWindowContext ? 'flex-1 min-w-0 overflow-hidden bg-background' : isClassicLayout ? 'flex-1 min-w-0 overflow-hidden' : 'flex-1 min-w-0 overflow-hidden rounded-md border border-border/80 bg-background'"
|
||||
@mousedown="rememberEditorContentSurface"
|
||||
>
|
||||
<div class="h-full flex min-h-0 min-w-0 flex-col">
|
||||
<AppTabBar
|
||||
|
||||
@@ -17,7 +17,9 @@ const appSource = readFileSync(new URL("../../../App.vue", import.meta.url), "ut
|
||||
function bodyOf(fnSignature: string): string {
|
||||
const start = appSource.indexOf(fnSignature);
|
||||
expect(start, `expected to find "${fnSignature}" in App.vue`).toBeGreaterThanOrEqual(0);
|
||||
const braceStart = appSource.indexOf("{", start);
|
||||
const closingParen = appSource.indexOf(")", start);
|
||||
const searchStart = closingParen >= 0 ? closingParen : start;
|
||||
const braceStart = appSource.indexOf("{", searchStart);
|
||||
let depth = 0;
|
||||
for (let i = braceStart; i < appSource.length; i++) {
|
||||
if (appSource[i] === "{") depth++;
|
||||
@@ -35,21 +37,30 @@ describe("new query entry context wiring", () => {
|
||||
});
|
||||
|
||||
it("resolves the shared new-query entry from the active tab and unique online SQL connection", () => {
|
||||
const body = bodyOf("async function newQuery()");
|
||||
// Without an explicit source the resolver defaults to the active tab first
|
||||
// and the selected sidebar node second, so all ad-hoc entries agree.
|
||||
expect(body).not.toContain("preferredSource");
|
||||
const body = bodyOf("async function newQuery");
|
||||
expect(body).toContain('quickConnectionOpenTarget(connection).kind === "query"');
|
||||
expect(body).toContain("connectedSqlConnectionIds,");
|
||||
expect(body).toContain("preferredSource: options.preferredSource");
|
||||
});
|
||||
|
||||
it("creates an unbound editor for manual SQL connection selection when the target is ambiguous", () => {
|
||||
const body = bodyOf("async function newQuery()");
|
||||
const body = bodyOf("async function newQuery");
|
||||
expect(body).toContain("if (sqlConnections.length > 0)");
|
||||
expect(body).toContain('queryStore.createTab("", "", undefined, "query")');
|
||||
});
|
||||
|
||||
it("keeps the editor-group entry focused on its own group", () => {
|
||||
expect(bodyOf("newQuery: (groupId: string) =>")).toContain("queryStore.focusGroup(groupId)");
|
||||
it("keeps the editor-group entry focused on its own group and tab context", () => {
|
||||
const body = bodyOf("newQuery: (groupId: string) =>");
|
||||
expect(body).toContain("queryStore.focusGroup(groupId)");
|
||||
expect(body).toContain('preferredSource: "tab"');
|
||||
});
|
||||
|
||||
it("routes keyboard shortcut with sidebar context when the sidebar is focused (#11801)", () => {
|
||||
const body = bodyOf("async function handleKeydown");
|
||||
expect(body).toContain('sidebarFocused ? "sidebar" : undefined');
|
||||
});
|
||||
|
||||
it("clears lastFocusedSidebarSurface when editor content is clicked", () => {
|
||||
expect(appSource).toContain("rememberEditorContentSurface");
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user