mirror of
https://github.com/t8y2/dbx.git
synced 2026-10-21 06:00:39 +00:00
修复驱动管理与侧边栏展开的前台显示问题
* 修复标签页切换和侧边栏展开滚动 * chore: rerun ci --------- Co-authored-by: staff <staff@qimaos-MacBook-Pro.local>
This commit is contained in:
@@ -339,6 +339,7 @@ watch(
|
||||
);
|
||||
}
|
||||
if (id) newQueryContextSource.value = "tab";
|
||||
if (id && showDriverStore.value) showDriverStore.value = false;
|
||||
selectedSql.value = "";
|
||||
activeOutputView.value = "result";
|
||||
if (id) queryStore.reloadEvictedTab(id);
|
||||
|
||||
@@ -13,7 +13,7 @@ import { usesTreeSchemaMode } from "@/lib/databaseFeatureSupport";
|
||||
import { connectionUsesDatabaseObjectTreeMode, effectiveDatabaseTypeForConnection } from "@/lib/jdbcDialect";
|
||||
import { activeTabSidebarTarget, findSidebarNodeForActiveTab, findSidebarNodeForTarget, findNodePathForTarget, scrollTopForSidebarNode, shouldScrollActiveSidebarSelection, type ActiveTabSidebarTarget } from "@/lib/sidebarActiveTabTarget";
|
||||
import { findLoadedTableTargetForCandidate, queryContextTargetFromCandidate, queryCursorTableCandidate, type QueryCursorTableCandidate } from "@/lib/queryCursorTableTarget";
|
||||
import { SIDEBAR_TREE_ROW_HEIGHT, SIDEBAR_TREE_PRERENDER_COUNT, SIDEBAR_TREE_SCROLL_BUFFER, flattenTree, scrollTopForExpandedTreeNode, shouldAutoScrollExpandedTreeNode, shouldVirtualizeFlatTree, type FlatTreeNode } from "@/composables/useFlatTree";
|
||||
import { SIDEBAR_TREE_ROW_HEIGHT, SIDEBAR_TREE_PRERENDER_COUNT, SIDEBAR_TREE_SCROLL_BUFFER, flattenTree, shouldVirtualizeFlatTree, type FlatTreeNode } from "@/composables/useFlatTree";
|
||||
import { sidebarTreeContextKey } from "@/lib/sidebarTreeContext";
|
||||
import TreeItem from "./TreeItem.vue";
|
||||
import { RecycleScroller } from "vue-virtual-scroller";
|
||||
@@ -451,29 +451,6 @@ function onSearchToggle(node: TreeNode) {
|
||||
searchCollapsedIds.value = next;
|
||||
}
|
||||
|
||||
async function onNodeToggled(node: TreeNode, wasExpanded: boolean) {
|
||||
if (wasExpanded || !node.isExpanded) return;
|
||||
if (!shouldAutoScrollExpandedTreeNode(node.type)) return;
|
||||
|
||||
await nextTick();
|
||||
|
||||
const expandedIndex = flatNodes.value.findIndex((item) => item.id === node.id);
|
||||
const insertedRowCount = flattenTree([node]).length - 1;
|
||||
const scroller = treeScrollerRef.value?.$el as HTMLElement | undefined;
|
||||
if (!scroller || expandedIndex < 0 || insertedRowCount <= 0) return;
|
||||
|
||||
const nextScrollTop = scrollTopForExpandedTreeNode({
|
||||
expandedIndex,
|
||||
insertedRowCount,
|
||||
currentScrollTop: scroller.scrollTop,
|
||||
viewportHeight: scroller.clientHeight,
|
||||
});
|
||||
|
||||
if (nextScrollTop !== scroller.scrollTop) {
|
||||
scroller.scrollTop = nextScrollTop;
|
||||
}
|
||||
}
|
||||
|
||||
function currentTreeScroller(): HTMLElement | null {
|
||||
return ((useVirtualTree.value ? treeScrollerRef.value?.$el : plainTreeScrollerRef.value) as HTMLElement | undefined) ?? null;
|
||||
}
|
||||
@@ -630,16 +607,7 @@ defineExpose({ focusSearch, createNewGroup });
|
||||
flow-mode
|
||||
>
|
||||
<template #default="{ item }">
|
||||
<TreeItem
|
||||
:node="item.node"
|
||||
:depth="item.depth"
|
||||
:drag-disabled="isFiltering"
|
||||
:pending-rename="pendingRenameGroupId === item.node.id"
|
||||
:highlighted="highlightedNodeId === item.node.id"
|
||||
@node-toggled="onNodeToggled"
|
||||
@search-toggle="onSearchToggle"
|
||||
@rename-started="pendingRenameGroupId = null"
|
||||
/>
|
||||
<TreeItem :node="item.node" :depth="item.depth" :drag-disabled="isFiltering" :pending-rename="pendingRenameGroupId === item.node.id" :highlighted="highlightedNodeId === item.node.id" @search-toggle="onSearchToggle" @rename-started="pendingRenameGroupId = null" />
|
||||
</template>
|
||||
</RecycleScroller>
|
||||
<div v-else-if="flatNodes.length > 0" ref="plainTreeScrollerRef" class="sidebar-tree min-h-0 flex-1 overflow-y-auto" :class="sidebarTreeOverflowClass" @click="clearSidebarSelection">
|
||||
@@ -651,7 +619,6 @@ defineExpose({ focusSearch, createNewGroup });
|
||||
:drag-disabled="isFiltering"
|
||||
:pending-rename="pendingRenameGroupId === item.node.id"
|
||||
:highlighted="highlightedNodeId === item.id"
|
||||
@node-toggled="onNodeToggled"
|
||||
@search-toggle="onSearchToggle"
|
||||
@rename-started="pendingRenameGroupId = null"
|
||||
/>
|
||||
|
||||
@@ -29,25 +29,3 @@ export function flattenTree(nodes: TreeNode[]): FlatTreeNode[] {
|
||||
export function shouldVirtualizeFlatTree(count: number): boolean {
|
||||
return count > 0;
|
||||
}
|
||||
|
||||
export function shouldAutoScrollExpandedTreeNode(type: TreeNodeType): boolean {
|
||||
return type !== "connection" && type !== "connection-group";
|
||||
}
|
||||
|
||||
export function scrollTopForExpandedTreeNode(options: { expandedIndex: number; insertedRowCount: number; currentScrollTop: number; viewportHeight: number; rowHeight?: number }): number {
|
||||
const rowHeight = options.rowHeight ?? SIDEBAR_TREE_ROW_HEIGHT;
|
||||
if (options.expandedIndex < 0 || options.insertedRowCount <= 0 || options.viewportHeight <= 0) {
|
||||
return options.currentScrollTop;
|
||||
}
|
||||
|
||||
const visibleRowCapacity = Math.max(1, Math.floor(options.viewportHeight / rowHeight) - 1);
|
||||
const rowsToReveal = Math.min(options.insertedRowCount, visibleRowCapacity);
|
||||
const expandedContentBottom = (options.expandedIndex + 1 + rowsToReveal) * rowHeight;
|
||||
const viewportBottom = options.currentScrollTop + options.viewportHeight;
|
||||
|
||||
if (expandedContentBottom <= viewportBottom) {
|
||||
return options.currentScrollTop;
|
||||
}
|
||||
|
||||
return Math.max(0, expandedContentBottom - options.viewportHeight);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { strict as assert } from "node:assert";
|
||||
import { test } from "vitest";
|
||||
import { SIDEBAR_TREE_ROW_HEIGHT, SIDEBAR_TREE_PRERENDER_COUNT, SIDEBAR_TREE_SCROLL_BUFFER, flattenTree, scrollTopForExpandedTreeNode, shouldAutoScrollExpandedTreeNode, shouldVirtualizeFlatTree } from "../../apps/desktop/src/composables/useFlatTree.ts";
|
||||
import { SIDEBAR_TREE_ROW_HEIGHT, SIDEBAR_TREE_PRERENDER_COUNT, SIDEBAR_TREE_SCROLL_BUFFER, flattenTree, shouldVirtualizeFlatTree } from "../../apps/desktop/src/composables/useFlatTree.ts";
|
||||
import type { TreeNode } from "../../apps/desktop/src/types/database.ts";
|
||||
|
||||
test("flattenTree preserves depth and node type for virtualized sidebar rows", () => {
|
||||
@@ -51,34 +51,3 @@ test("sidebar virtual tree keeps enough buffered rows for fast scrolling", () =>
|
||||
test("sidebar virtual tree prerenders enough rows for the first frame", () => {
|
||||
assert.ok(SIDEBAR_TREE_PRERENDER_COUNT >= 40);
|
||||
});
|
||||
|
||||
test("sidebar keeps root connection expansion from changing scroll position", () => {
|
||||
assert.equal(shouldAutoScrollExpandedTreeNode("connection"), false);
|
||||
assert.equal(shouldAutoScrollExpandedTreeNode("connection-group"), false);
|
||||
assert.equal(shouldAutoScrollExpandedTreeNode("database"), true);
|
||||
assert.equal(shouldAutoScrollExpandedTreeNode("group-columns"), true);
|
||||
});
|
||||
|
||||
test("expanded sidebar nodes scroll enough to reveal inserted rows", () => {
|
||||
assert.equal(
|
||||
scrollTopForExpandedTreeNode({
|
||||
expandedIndex: 20,
|
||||
insertedRowCount: 2,
|
||||
currentScrollTop: 15 * SIDEBAR_TREE_ROW_HEIGHT,
|
||||
viewportHeight: 6 * SIDEBAR_TREE_ROW_HEIGHT,
|
||||
}),
|
||||
17 * SIDEBAR_TREE_ROW_HEIGHT,
|
||||
);
|
||||
});
|
||||
|
||||
test("expanded sidebar nodes keep scroll position when children are already visible", () => {
|
||||
assert.equal(
|
||||
scrollTopForExpandedTreeNode({
|
||||
expandedIndex: 4,
|
||||
insertedRowCount: 2,
|
||||
currentScrollTop: 0,
|
||||
viewportHeight: 8 * SIDEBAR_TREE_ROW_HEIGHT,
|
||||
}),
|
||||
0,
|
||||
);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user