mirror of
https://github.com/t8y2/dbx.git
synced 2026-10-19 16:16:45 +00:00
fix(sidebar): hide connection utility nodes in search results
This commit is contained in:
@@ -4,7 +4,14 @@ import { buildTableTreeNodes } from "@/lib/table/tableTree";
|
||||
import { stripTableVGroupsFromChildren } from "@/lib/table/tableVGroup";
|
||||
|
||||
const preserveMatchedSubtreeTypes = new Set(["connection", "database", "schema", "table", "view", "mongo-db", "mongo-collection"]);
|
||||
const hiddenSearchNodeTypes = new Set<TreeNodeType>(["user-admin", "dameng-job-admin"]);
|
||||
// Synthetic connection utility entries (the isConnectionUtilityNode types in
|
||||
// connectionStore) are admin/navigation shortcuts, not schema objects. Their
|
||||
// labels are i18n keys that can never match a text query, so they never
|
||||
// self-match — but a few of them (oracle-db-links, group-tablespaces) are
|
||||
// groups whose children ARE real objects, so their children stay searchable
|
||||
// and the group only survives through a child hit. saved-sql-root is exempt:
|
||||
// its saved queries are real searchable files rather than a shortcut.
|
||||
const hiddenSearchNodeTypes = new Set<TreeNodeType>(["user-admin", "dameng-users", "dameng-roles", "dameng-job-admin", "group-tablespaces", "oracle-db-links"]);
|
||||
|
||||
function bestMatch(matchLabel: SidebarLabelMatcher, label: string, comment?: string | null, aliases?: readonly string[]) {
|
||||
let best = matchLabel(label);
|
||||
@@ -360,7 +367,11 @@ function filterSidebarTreeWithMatcher(nodes: TreeNode[], matchLabel: SidebarLabe
|
||||
const filteredNodes: { node: TreeNode; score: number }[] = [];
|
||||
|
||||
for (const node of nodes) {
|
||||
if (matchLabel && hiddenSearchNodeTypes.has(node.type)) continue;
|
||||
// Utility groups never match by their own label; groups without children
|
||||
// (or not yet loaded) drop out entirely, while groups that hold real
|
||||
// objects (db links, tablespaces) survive through a matching child.
|
||||
const hiddenUtility = !!matchLabel && hiddenSearchNodeTypes.has(node.type);
|
||||
if (hiddenUtility && !node.children?.length) continue;
|
||||
if (node.type === "object-browser" && node.hiddenChildren) {
|
||||
const matches = node.hiddenChildren.flatMap((child) => {
|
||||
if (searchableNodeTypes && !searchableNodeTypes.has(child.type)) return [];
|
||||
@@ -373,7 +384,7 @@ function filterSidebarTreeWithMatcher(nodes: TreeNode[], matchLabel: SidebarLabe
|
||||
}
|
||||
|
||||
const label = normalizedLabel(node, resolveLabel);
|
||||
const canSelfMatch = !searchableNodeTypes || searchableNodeTypes.has(node.type);
|
||||
const canSelfMatch = (!searchableNodeTypes || searchableNodeTypes.has(node.type)) && !hiddenUtility;
|
||||
const selfMatch = canSelfMatch ? (matchLabel ? bestMatch(matchLabel, label, node.comment, node.searchAliases) : { score: 0 }) : null;
|
||||
// Type-only filtering keeps matching rows and their ancestor path, but not
|
||||
// unrelated descendants that would make the selected type appear ignored.
|
||||
|
||||
+109
@@ -318,6 +318,20 @@ test("omits synthetic connection management entries when the connection itself m
|
||||
connectionId: "conn:1",
|
||||
database: "",
|
||||
},
|
||||
{
|
||||
id: "conn:1:__dameng_users",
|
||||
label: "tree.damengUsers",
|
||||
type: "dameng-users",
|
||||
connectionId: "conn:1",
|
||||
database: "",
|
||||
},
|
||||
{
|
||||
id: "conn:1:__dameng_roles",
|
||||
label: "tree.damengRoles",
|
||||
type: "dameng-roles",
|
||||
connectionId: "conn:1",
|
||||
database: "",
|
||||
},
|
||||
{
|
||||
id: "conn:1:__dameng_jobs",
|
||||
label: "tree.damengJobAdmin",
|
||||
@@ -325,6 +339,20 @@ test("omits synthetic connection management entries when the connection itself m
|
||||
connectionId: "conn:1",
|
||||
database: "",
|
||||
},
|
||||
{
|
||||
id: "conn:1:__xugu_tablespaces",
|
||||
label: "tree.xuguTablespaces",
|
||||
type: "group-tablespaces",
|
||||
connectionId: "conn:1",
|
||||
database: "",
|
||||
},
|
||||
{
|
||||
id: "conn:1:__oracle_db_links",
|
||||
label: "tree.databaseLinks",
|
||||
type: "oracle-db-links",
|
||||
connectionId: "conn:1",
|
||||
database: "",
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
||||
@@ -354,6 +382,14 @@ test("keeps a disconnected connection search result collapsed when it only has s
|
||||
connectionId: "conn:1",
|
||||
database: "",
|
||||
},
|
||||
{
|
||||
id: "conn:1:__oracle_db_links",
|
||||
label: "tree.databaseLinks",
|
||||
type: "oracle-db-links",
|
||||
connectionId: "conn:1",
|
||||
database: "",
|
||||
children: [],
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
||||
@@ -364,6 +400,79 @@ test("keeps a disconnected connection search result collapsed when it only has s
|
||||
assert.equal(filtered[0]?.isExpanded, false);
|
||||
});
|
||||
|
||||
test("keeps utility groups searchable through their real object children", () => {
|
||||
const nodes: TreeNode[] = [
|
||||
{
|
||||
id: "conn:1",
|
||||
label: "prod",
|
||||
type: "connection",
|
||||
connectionId: "conn:1",
|
||||
isExpanded: true,
|
||||
children: [
|
||||
{
|
||||
id: "conn:1:__oracle_db_links",
|
||||
label: "tree.databaseLinks",
|
||||
type: "oracle-db-links",
|
||||
connectionId: "conn:1",
|
||||
database: "",
|
||||
children: [
|
||||
{
|
||||
id: "conn:1:__oracle_db_links:reporting",
|
||||
label: "REPORTING.LOCALDOMAIN",
|
||||
type: "oracle-db-link",
|
||||
connectionId: "conn:1",
|
||||
database: "",
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
const filtered = filterSidebarTree(nodes, "reporting", new Set());
|
||||
|
||||
assert.equal(filtered[0]?.type, "connection");
|
||||
assert.deepEqual(
|
||||
filtered[0]?.children?.map((child) => child.type),
|
||||
["oracle-db-links"],
|
||||
);
|
||||
assert.equal(filtered[0]?.children?.[0]?.children?.[0]?.label, "REPORTING.LOCALDOMAIN");
|
||||
});
|
||||
|
||||
test("drops utility groups whose children do not match the query", () => {
|
||||
const nodes: TreeNode[] = [
|
||||
{
|
||||
id: "conn:1",
|
||||
label: "prod",
|
||||
type: "connection",
|
||||
connectionId: "conn:1",
|
||||
isExpanded: true,
|
||||
children: [
|
||||
{
|
||||
id: "conn:1:__xugu_tablespaces",
|
||||
label: "tree.xuguTablespaces",
|
||||
type: "group-tablespaces",
|
||||
connectionId: "conn:1",
|
||||
database: "",
|
||||
children: [
|
||||
{
|
||||
id: "conn:1:__xugu_tablespaces:system",
|
||||
label: "SYSTEM",
|
||||
type: "tablespace",
|
||||
connectionId: "conn:1",
|
||||
database: "",
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
const filtered = filterSidebarTree(nodes, "reporting", new Set());
|
||||
|
||||
assert.deepEqual(filtered, []);
|
||||
});
|
||||
|
||||
test("does not return synthetic connection management entries as direct text matches", () => {
|
||||
const nodes: TreeNode[] = [
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user