feat(settings): improve sidebar search

- 新增设置选项以启用/禁用数据库内的表搜索
- 更新相关组件以支持表搜索功能
- 添加多语言支持的描述信息
This commit is contained in:
二丫讲梵 authored and GitHub committed 2026-07-06 17:24:56 +08:00
1 parent 7ccc632ce8
commit 35d5e90378
13 files changed
+113 -3

No files matched your search

@@ -276,6 +276,7 @@ const editingShortcutId = ref<ShortcutActionId | null>(null);
const editSidebarActivation = ref(settingsStore.editorSettings.sidebarActivation);
const editSidebarObjectDisplay = ref(settingsStore.editorSettings.sidebarObjectDisplay);
const sidebarObjectDisplayHelp = ref<"grouped" | "simple" | null>(null);
const editSidebarTableSearchEnabled = ref(settingsStore.editorSettings.sidebarTableSearchEnabled);
const editAutoSelectActiveSidebarNode = ref(settingsStore.editorSettings.autoSelectActiveSidebarNode);
const editOpenTabsRestoreMode = ref<OpenTabsRestoreMode>(settingsStore.editorSettings.openTabsRestoreMode);
const editDisconnectTabHandlingMode = ref<DisconnectTabHandlingMode>(settingsStore.editorSettings.disconnectTabHandlingMode);
@@ -570,6 +571,7 @@ watch(
sqlFormatterConfigValid.value = true;
editSidebarActivation.value = settingsStore.editorSettings.sidebarActivation;
editSidebarObjectDisplay.value = settingsStore.editorSettings.sidebarObjectDisplay;
editSidebarTableSearchEnabled.value = settingsStore.editorSettings.sidebarTableSearchEnabled;
editAutoSelectActiveSidebarNode.value = settingsStore.editorSettings.autoSelectActiveSidebarNode;
editOpenTabsRestoreMode.value = settingsStore.editorSettings.openTabsRestoreMode;
editDisconnectTabHandlingMode.value = settingsStore.editorSettings.disconnectTabHandlingMode;
@@ -661,6 +663,7 @@ function hasChanges(): boolean {
JSON.stringify(editSqlFormatter.value) !== JSON.stringify(normalizeSqlFormatterSettings(settingsStore.editorSettings.sqlFormatter)) ||
editSidebarActivation.value !== settingsStore.editorSettings.sidebarActivation ||
editSidebarObjectDisplay.value !== settingsStore.editorSettings.sidebarObjectDisplay ||
editSidebarTableSearchEnabled.value !== settingsStore.editorSettings.sidebarTableSearchEnabled ||
editAutoSelectActiveSidebarNode.value !== settingsStore.editorSettings.autoSelectActiveSidebarNode ||
editOpenTabsRestoreMode.value !== settingsStore.editorSettings.openTabsRestoreMode ||
editDisconnectTabHandlingMode.value !== settingsStore.editorSettings.disconnectTabHandlingMode ||
@@ -711,6 +714,7 @@ async function persistSettings() {
sqlFormatter: normalizeSqlFormatterSettings(editSqlFormatter.value),
sidebarActivation: editSidebarActivation.value,
sidebarObjectDisplay: editSidebarObjectDisplay.value,
sidebarTableSearchEnabled: editSidebarTableSearchEnabled.value,
autoSelectActiveSidebarNode: editAutoSelectActiveSidebarNode.value,
openTabsRestoreMode: editOpenTabsRestoreMode.value,
disconnectTabHandlingMode: editDisconnectTabHandlingMode.value,
@@ -800,6 +804,7 @@ function resetDefaultsForTab(tab: SettingsCategory) {
editSidebarTablePageSize.value = DEFAULT_SIDEBAR_TABLE_PAGE_SIZE;
editSidebarActivation.value = DEFAULT_EDITOR_SETTINGS.sidebarActivation;
editSidebarObjectDisplay.value = DEFAULT_EDITOR_SETTINGS.sidebarObjectDisplay;
editSidebarTableSearchEnabled.value = DEFAULT_EDITOR_SETTINGS.sidebarTableSearchEnabled;
editAutoSelectActiveSidebarNode.value = DEFAULT_EDITOR_SETTINGS.autoSelectActiveSidebarNode;
editOpenTabsRestoreMode.value = DEFAULT_EDITOR_SETTINGS.openTabsRestoreMode;
editDisconnectTabHandlingMode.value = DEFAULT_EDITOR_SETTINGS.disconnectTabHandlingMode;
@@ -870,6 +875,7 @@ function resetAllDefaults() {
sqlFormatterConfigValid.value = true;
editSidebarActivation.value = DEFAULT_EDITOR_SETTINGS.sidebarActivation;
editSidebarObjectDisplay.value = DEFAULT_EDITOR_SETTINGS.sidebarObjectDisplay;
editSidebarTableSearchEnabled.value = DEFAULT_EDITOR_SETTINGS.sidebarTableSearchEnabled;
editAutoSelectActiveSidebarNode.value = DEFAULT_EDITOR_SETTINGS.autoSelectActiveSidebarNode;
editOpenTabsRestoreMode.value = DEFAULT_EDITOR_SETTINGS.openTabsRestoreMode;
editDisconnectTabHandlingMode.value = DEFAULT_EDITOR_SETTINGS.disconnectTabHandlingMode;
@@ -2854,6 +2860,15 @@ onUnmounted(cleanupPreviewEditor);
</Button>
</div>
</div>
<div class="flex items-center justify-between gap-4 rounded-md border bg-muted/20 px-3 py-2">
<div class="flex items-center gap-2">
<Label for="sidebar-table-search-enabled">{{ t("settings.sidebarTableSearchEnabled") }}</Label>
<HelpTooltip :label="t('settings.sidebarTableSearchEnabled')">
{{ t("settings.sidebarTableSearchEnabledDescription") }}
</HelpTooltip>
</div>
<Switch id="sidebar-table-search-enabled" v-model="editSidebarTableSearchEnabled" />
</div>
<div class="flex items-center justify-between gap-4 rounded-md border bg-muted/20 px-3 py-2">
<div class="flex items-center gap-2">
<Label for="auto-select-active-sidebar-node">{{ t("settings.autoSelectActiveSidebarNode") }}</Label>
@@ -73,6 +73,24 @@ function refreshActiveSidebarTableSearches() {
}
}
watch(
() => settingsStore.editorSettings.sidebarTableSearchEnabled,
(enabled) => {
if (enabled) return;
const parentNodeIds = Object.keys(store.sidebarTableSearchQueries);
if (parentNodeIds.length === 0) return;
for (const parentNodeId of parentNodeIds) {
window.clearTimeout(tableSearchTimers.get(parentNodeId));
tableSearchTimers.delete(parentNodeId);
tableSearchFocusRestoreTokens.delete(parentNodeId);
store.setSidebarTableSearchQuery(parentNodeId, "");
}
latestTableSearchInteractionParentId = null;
void Promise.all(parentNodeIds.map((parentNodeId) => store.refreshSidebarTableSearch(parentNodeId))).catch(() => {});
},
);
watch(deferredSearchQuery, (newQuery, oldQuery) => {
store.sidebarSearchQuery = newQuery;
const tasks: Promise<void>[] = [];
@@ -256,7 +274,7 @@ const filteredNodes = computed(() => {
const flatNodes = computed<FlatTreeNode[]>(() =>
insertSidebarTableSearchControls(flattenTree(filteredNodes.value), {
enabled: !isFiltering.value,
enabled: settingsStore.editorSettings.sidebarTableSearchEnabled && !isFiltering.value,
sidebarObjectDisplay: settingsStore.editorSettings.sidebarObjectDisplay,
activeQueries: store.sidebarTableSearchQueries,
}),
@@ -3944,6 +3944,16 @@ const rowStyle = computed(() => {
"--tree-connection-active-focus-bg": hexToRgba(color, 0.22),
};
});
const tableSearchStyle = computed(() => {
const color = connectionColor.value;
const rowBackgroundColor = color ? hexToRgba(color, isActiveConnectionScope.value ? 0.14 : 0.08) : "transparent";
return {
paddingLeft: paddingLeft.value,
"--tree-table-search-row-bg": rowBackgroundColor,
"--tree-table-search-input-bg": color ? hexToRgba(color, isActiveConnectionScope.value ? 0.05 : 0.03) : "hsl(var(--background) / 0.56)",
"--tree-table-search-border": color ? hexToRgba(color, isActiveConnectionScope.value ? 0.12 : 0.08) : "hsl(var(--border) / 0.36)",
};
});
function togglePin() {
connectionStore.toggleTreeNodePin(props.node.id);
@@ -4933,7 +4943,7 @@ function treeItemMenuItems(): ContextMenuItem[] {
</script>
<template>
<div v-if="node.type === 'table-search-control'" class="flex h-7 items-center py-0.5 pr-2" :style="{ paddingLeft }" @click.stop @dblclick.stop @mousedown.stop @keydown.stop>
<div v-if="node.type === 'table-search-control'" class="tree-table-search-control flex h-7 items-center py-0.5 pr-2" :style="tableSearchStyle" @click.stop @dblclick.stop @mousedown.stop @keydown.stop>
<div class="relative w-full min-w-0">
<Search class="pointer-events-none absolute left-2 top-1/2 h-3 w-3 -translate-y-1/2 text-muted-foreground" />
<Input
@@ -4941,7 +4951,8 @@ function treeItemMenuItems(): ContextMenuItem[] {
autocapitalize="off"
autocorrect="off"
spellcheck="false"
class="h-6 w-full rounded border-border/70 bg-background pl-7 pr-6 text-xs shadow-none focus-visible:ring-1"
class="h-6 w-full rounded border pl-7 pr-6 text-xs shadow-none focus-visible:ring-1"
:style="{ backgroundColor: 'var(--tree-table-search-input-bg)', borderColor: 'var(--tree-table-search-border)' }"
:placeholder="t(node.label)"
:aria-label="t(node.label)"
:data-sidebar-table-search-parent-id="tableSearchParentId"
@@ -5606,6 +5617,26 @@ function treeItemMenuItems(): ContextMenuItem[] {
background-color: var(--tree-connection-active-focus-bg, var(--tree-connection-active-bg));
}
.tree-table-search-control {
position: relative;
isolation: isolate;
background-color: transparent;
}
.tree-table-search-control::before {
content: "";
position: absolute;
inset: 0 -9999px;
z-index: 0;
background-color: var(--tree-table-search-row-bg);
pointer-events: none;
}
.tree-table-search-control > * {
position: relative;
z-index: 1;
}
/* Unfocused: subtle gray */
.tree-item-active {
background-color: var(--tree-connection-active-bg, rgb(235 235 235)) !important;