fix(ui): route blank-focus ctrl+f to the sidebar search

This commit is contained in:
zipg
2026-09-16 00:40:25 +08:00
committed by GitHub
parent 1938c4a8aa
commit 7f12fecc08
2 changed files with 17 additions and 1 deletions
+15 -1
View File
@@ -369,6 +369,7 @@ const appSidebarRef = ref<InstanceType<typeof AppSidebar> | null>(null);
const appTabBarRef = ref<InstanceType<typeof AppTabBar> | null>(null);
const contentAreaRef = ref<InstanceType<typeof SqlEditorWorkspace> | null>(null);
const lastFocusedAuxiliarySurface = ref<AuxiliarySearchSurface>(null);
const lastFocusedSidebarSurface = ref(false);
const selectedSql = ref("");
const cursorPos = ref(0);
@@ -1434,6 +1435,7 @@ function setRightSidebarPanelOpen(panelId: RightSidebarPanelId, open: boolean) {
lastOpenedRightSidebarPanel = panelId;
if (panelId === "ai" || panelId === "history" || panelId === "sqlLibrary") {
lastFocusedAuxiliarySurface.value = panelId;
lastFocusedSidebarSurface.value = false;
}
} else if (lastOpenedRightSidebarPanel === panelId) {
lastOpenedRightSidebarPanel = RIGHT_SIDEBAR_PANEL_IDS.find((candidate) => rightSidebarPanelRefs[candidate].value);
@@ -3225,6 +3227,10 @@ function focusSearchInAuxiliarySurface(target: Element | null): boolean {
if (showHistory.value && target?.closest("[data-history-panel], [data-history-search]")) return focusSearchInput("[data-history-search]");
if (showSqlLibraryPanel.value && target?.closest("[data-sql-library-panel], [data-sql-library-search]")) return focusSearchInput("[data-sql-library-search]");
const targetIsDocument = !target || target === document.body || target === document.documentElement;
if (!targetIsDocument) return false;
if (lastFocusedSidebarSurface.value) return false;
if (lastFocusedAuxiliarySurface.value === "ai" && showAiPanel.value) {
if (aiAssistantRef.value) return aiAssistantRef.value.focusSearch();
invokeWhenAiReady((handle) => handle.focusSearch());
@@ -3237,6 +3243,11 @@ function focusSearchInAuxiliarySurface(target: Element | null): boolean {
function rememberAuxiliarySearchSurface(surface: Exclude<AuxiliarySearchSurface, null>) {
lastFocusedAuxiliarySurface.value = surface;
lastFocusedSidebarSurface.value = false;
}
function rememberSidebarSearchSurface() {
lastFocusedSidebarSurface.value = true;
}
function setPluginWorkbenchTabRef(tabId: string, element: unknown) {
@@ -3315,7 +3326,9 @@ async function handleKeydown(e: KeyboardEvent) {
// Otherwise Ctrl+F from empty space in the sidebar incorrectly opens the
// search belonging to the active table/query tab.
const target = e.target instanceof Element ? e.target : null;
const focused = target?.closest("[data-app-sidebar]") ? appSidebarRef.value?.focusSearch(target) : focusSearchInAuxiliarySurface(target) || contentAreaRef.value?.focusSearch(target) || appSidebarRef.value?.focusSearch(target);
const targetIsDocument = !target || target === document.body || target === document.documentElement;
const sidebarFocused = target?.closest("[data-app-sidebar]") || (targetIsDocument && lastFocusedSidebarSurface.value);
const focused = sidebarFocused ? appSidebarRef.value?.focusSearch(target) : focusSearchInAuxiliarySurface(target) || contentAreaRef.value?.focusSearch(target) || appSidebarRef.value?.focusSearch(target);
if (focused) {
e.preventDefault();
e.stopPropagation();
@@ -3771,6 +3784,7 @@ onUnmounted(() => {
@collapse="setSidebarOpen(false)"
@open-settings="(initialTab) => openSettings(initialTab ?? 'appearance')"
@add-to-ai="addToAi"
@mousedown="rememberSidebarSearchSurface"
/>
<div v-show="!isAiPanelMaximized || 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'">
@@ -38,6 +38,8 @@ describe("search shortcut focus routing", () => {
it("routes auxiliary page and panel searches before the query surface", () => {
expect(appSource).toMatch(/function focusSearchInAuxiliarySurface\(target: Element \| null\)[\s\S]*data-connection-db-search[\s\S]*data-settings-global-search[\s\S]*data-driver-store-agent-search[\s\S]*data-plugin-marketplace-search[\s\S]*data-history-panel[\s\S]*data-sql-library-panel/);
expect(appSource).toMatch(/lastFocusedAuxiliarySurface[\s\S]*rememberAuxiliarySearchSurface[\s\S]*data-sql-library-panel/);
expect(appSource).toMatch(/const targetIsDocument = !target \|\| target === document\.body \|\| target === document\.documentElement;[\s\S]*if \(!targetIsDocument\) return false;/);
expect(appSource).toMatch(/lastFocusedSidebarSurface[\s\S]*rememberSidebarSearchSurface[\s\S]*data-app-sidebar/);
expect(appSource).toMatch(/function handleAuxiliarySearchKeydownCapture\(e: KeyboardEvent\)[\s\S]*focusSearchInAuxiliarySurface\(target\)[\s\S]*addEventListener\("keydown", handleAuxiliarySearchKeydownCapture, true\)/);
expect(appSource).toContain("aiAssistantRef.value.focusSearch()");
expect(aiAssistantSource).toMatch(/function focusSearch\(\): boolean[\s\S]*setConversationListOpen\(true\)/);