feat(settings): improve sidebar search
- 新增设置选项以启用/禁用数据库内的表搜索 - 更新相关组件以支持表搜索功能 - 添加多语言支持的描述信息
This commit is contained in:
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;
|
||||
|
||||
Reference in new issue
Block a user