From 3e26b7769b7bae98ebfb13c40b38bfb2407aee0e Mon Sep 17 00:00:00 2001 From: Elias <45232878+mapan0424@users.noreply.github.com> Date: Tue, 28 Jul 2026 23:22:11 +0800 Subject: [PATCH] fix(tree): label Xugu table child groups --- .../src/components/sidebar/TreeItem.vue | 27 ++++++------------- .../__tests__/sidebar/treeNodeGroup.spec.ts | 16 +++++++++++ apps/desktop/src/lib/sidebar/treeNodeGroup.ts | 25 +++++++++++++++++ 3 files changed, 49 insertions(+), 19 deletions(-) create mode 100644 apps/desktop/src/lib/__tests__/sidebar/treeNodeGroup.spec.ts create mode 100644 apps/desktop/src/lib/sidebar/treeNodeGroup.ts diff --git a/apps/desktop/src/components/sidebar/TreeItem.vue b/apps/desktop/src/components/sidebar/TreeItem.vue index 4b0e68285..79a2d91de 100644 --- a/apps/desktop/src/components/sidebar/TreeItem.vue +++ b/apps/desktop/src/components/sidebar/TreeItem.vue @@ -44,7 +44,7 @@ import ProductionContextBadge from "@/components/common/ProductionContextBadge.v import { Badge } from "@/components/ui/badge"; import { Input } from "@/components/ui/input"; import LightTooltip from "@/components/ui/LightTooltip.vue"; -import type { ColumnInfo, ConnectionConfig, DatabaseType, TreeNode, TreeNodeType } from "@/types/database"; +import type { ColumnInfo, ConnectionConfig, DatabaseType, TreeNode } from "@/types/database"; import { alignedCommentLeadingWidth, canTreeNodePin, canTreeNodeShowExpander, sidebarTreeNodeComment, trailingCommentAvailableWidth, trailingCommentGapPx, treeItemPaddingLeft, treeLabelWidthClass, usesFullWidthTreeLabel } from "@/lib/sidebar/sidebarTreeItemLayout"; import { clearActiveTableReferencePayload, createTableReferencePayload, createTableReferenceDropEvent, setActiveTableReferencePayload, type QueryEditorTableReferencePayload } from "@/lib/editor/queryEditorTableDrop"; import { formatSidebarObjectStorage } from "@/lib/sidebar/sidebarDatabaseStorage"; @@ -64,6 +64,7 @@ import { focusSidebarRenameInput } from "@/lib/sidebar/sidebarRenameFocus"; import { useDragSort } from "@/composables/useDragSort"; import { sidebarTreeRuntimeKey } from "@/lib/sidebar/sidebarTreeRuntime"; import { treeNodePinKey } from "@/lib/app/pinnedItems"; +import { isTreeGroupNodeType } from "@/lib/sidebar/treeNodeGroup"; const { t } = useI18n(); @@ -226,6 +227,11 @@ function getIconInfo(node: TreeNode): { icon: any; colorClass: string } | null { return { icon: Link, colorClass: "text-blue-400" }; case "group-triggers": return { icon: Zap, colorClass: "text-orange-400" }; + case "group-constraints": + return { icon: Key, colorClass: "text-amber-500" }; + case "group-table-partitions": + case "group-table-subpartitions": + return { icon: node.isExpanded ? FolderOpen : FolderClosed, colorClass: "text-green-400" }; case "object-browser": return { icon: TableProperties, colorClass: "text-primary" }; case "user-admin": @@ -306,25 +312,8 @@ function getIconInfo(node: TreeNode): { icon: any; colorClass: string } | null { } } -const groupTypes: Set = new Set([ - "group-columns", - "group-indexes", - "group-fkeys", - "group-triggers", - "group-tables", - "group-views", - "group-materialized-views", - "group-procedures", - "group-functions", - "group-sequences", - "group-packages", - "group-types", - "group-partitions", - "group-extensions", -]); - function isGroupLabel(node: TreeNode): boolean { - return groupTypes.has(node.type); + return isTreeGroupNodeType(node.type); } function displayLabel(node: TreeNode): string { diff --git a/apps/desktop/src/lib/__tests__/sidebar/treeNodeGroup.spec.ts b/apps/desktop/src/lib/__tests__/sidebar/treeNodeGroup.spec.ts new file mode 100644 index 000000000..e9ee8c134 --- /dev/null +++ b/apps/desktop/src/lib/__tests__/sidebar/treeNodeGroup.spec.ts @@ -0,0 +1,16 @@ +import { describe, expect, it } from "vitest"; +import { isTreeGroupNodeType } from "@/lib/sidebar/treeNodeGroup"; + +describe("isTreeGroupNodeType", () => { + it("recognizes Xugu table child groups as translated tree groups", () => { + expect(isTreeGroupNodeType("group-constraints")).toBe(true); + expect(isTreeGroupNodeType("group-table-partitions")).toBe(true); + expect(isTreeGroupNodeType("group-table-subpartitions")).toBe(true); + }); + + it("does not classify Xugu child objects as groups", () => { + expect(isTreeGroupNodeType("constraint")).toBe(false); + expect(isTreeGroupNodeType("partition")).toBe(false); + expect(isTreeGroupNodeType("subpartition")).toBe(false); + }); +}); diff --git a/apps/desktop/src/lib/sidebar/treeNodeGroup.ts b/apps/desktop/src/lib/sidebar/treeNodeGroup.ts new file mode 100644 index 000000000..9852ab38c --- /dev/null +++ b/apps/desktop/src/lib/sidebar/treeNodeGroup.ts @@ -0,0 +1,25 @@ +import type { TreeNodeType } from "@/types/database"; + +const treeGroupNodeTypes = new Set([ + "group-columns", + "group-indexes", + "group-fkeys", + "group-triggers", + "group-constraints", + "group-table-partitions", + "group-table-subpartitions", + "group-tables", + "group-views", + "group-materialized-views", + "group-procedures", + "group-functions", + "group-sequences", + "group-packages", + "group-types", + "group-partitions", + "group-extensions", +]); + +export function isTreeGroupNodeType(type: TreeNodeType): boolean { + return treeGroupNodeTypes.has(type); +}