feat(redis): limit the sidebar database list

This commit is contained in:
Melody Ruch authored and GitHub committed 2026-09-18 17:33:28 +08:00
1 parent 745c201f06
commit ec356293aa
18 files changed
+265 -22

No files matched your search

+32 -21
View File
@@ -145,7 +145,7 @@ import { completionSchemasFromTree, completionTablesFromTree } from "@/lib/metad
import { kvRootNodeLabel } from "@/lib/kv/kvRootPresentation";
import { etcdPermissionsAllowKey } from "@/lib/etcd/keyPermissions";
import { REDIS_SCAN_PAGE_SIZE_DEFAULT } from "@/lib/redis/redisKeyPattern";
import { normalizeRedisDatabaseAliases, redisDatabaseAlias, redisDatabaseLabel } from "@/lib/redis/redisDatabaseAlias";
import { limitRedisDatabaseList, normalizeRedisDatabaseAliases, redisDatabaseAlias, redisDatabaseLabel } from "@/lib/redis/redisDatabaseAlias";
import { normalizeRedisKeyTemplates } from "@/lib/redis/redisKeyTemplates";
import { appendAgentDriverUpdateHint, connectionUsesSsh, hasAgentDriverUpdate, hasInstalledAgentVersion, type AgentDriverInstallState } from "@/lib/connection/agentDriverInstallHint";
import { appendConnectionErrorHints, isMysqlMissingPasswordFailure, isSqliteMissingEncryptionPasswordFailure } from "@/lib/connection/connectionErrorHints";
@@ -4841,7 +4841,7 @@ export const useConnectionStore = defineStore("connection", () => {
}
}
async function loadRedisDatabases(connectionId: string) {
async function loadRedisDatabases(connectionId: string, options?: { showAll?: boolean }) {
const node = findConnectionNode(connectionId);
return runConnectionTreeMetadataLoad(connectionId, node, async (load) => {
const dbs = await withMetadataLoadTimeout(connectionId, api.redisListDatabases(connectionId), "Redis databases");
@@ -4857,26 +4857,25 @@ export const useConnectionStore = defineStore("connection", () => {
connectionId,
dbs.map((db) => String(db.db)),
);
setChildren(
targetNode,
withSavedSqlRoot(
const databaseNodes: TreeNode[] = dbs
.filter((db) => visibleNameSet.has(String(db.db)))
.map((db) => ({
id: `${connectionId}:db${db.db}`,
label: redisDatabaseLabel(db.db, config?.redis_database_aliases, db.keys),
type: "redis-db" as const,
connectionId,
dbs
.filter((db) => visibleNameSet.has(String(db.db)))
.map((db) => ({
id: `${connectionId}:db${db.db}`,
label: redisDatabaseLabel(db.db, config?.redis_database_aliases, db.keys),
type: "redis-db" as const,
connectionId,
database: String(db.db),
loadedKeyCount: 0,
totalKeyCount: db.keys,
isExpanded: false,
children: [],
})),
targetNode,
),
);
database: String(db.db),
loadedKeyCount: 0,
totalKeyCount: db.keys,
isExpanded: false,
children: [],
}));
// #1236: a `databases` count in the low hundreds is rare but not unheard
// of, and dumping every one of them into the sidebar at once is the
// reported pain point. Cap the initial render and let a "load more" node
// reveal the rest on demand, unless the user explicitly asked to see all.
const { visible, hasMore } = options?.showAll ? { visible: databaseNodes, hasMore: false } : limitRedisDatabaseList(databaseNodes, useSettingsStore().editorSettings.redisDatabaseDisplayLimit);
setChildren(targetNode, withSavedSqlRoot(connectionId, hasMore ? [...visible, buildLoadMoreNode(targetNode, visible.length, databaseNodes.length - visible.length)] : visible, targetNode));
targetNode.isExpanded = true;
});
}
@@ -6127,6 +6126,18 @@ export const useConnectionStore = defineStore("connection", () => {
if (node.type !== "load-more" || !node.loadMore) return;
const loadMore = node.loadMore;
const parent = findNode(treeNodes.value, node.loadMore.parentId);
if (parent?.type === "connection" && parent.connectionId && getConfig(parent.connectionId)?.db_type === "redis") {
// The full database list is already fetched in one cheap call, so "load
// more" here just re-renders it without the display-limit truncation
// instead of paging through another backend round trip.
node.isLoading = true;
try {
await loadRedisDatabases(parent.connectionId, { showAll: true });
} finally {
node.isLoading = false;
}
return;
}
if (!parent?.connectionId || !hasTreeNodeDatabaseContext(parent)) return;
const parentConnectionId = parent.connectionId;
const configForScope = getConfig(parentConnectionId);