diff --git a/apps/desktop/src/components/sidebar/TreeItem.vue b/apps/desktop/src/components/sidebar/TreeItem.vue
index 9355e387fc..514226ac1b 100644
--- a/apps/desktop/src/components/sidebar/TreeItem.vue
+++ b/apps/desktop/src/components/sidebar/TreeItem.vue
@@ -86,7 +86,12 @@ import {
usesTreeSchemaMode,
usesFetchFirst,
} from "@/lib/databaseCapabilities";
-import { sidebarSelectionCopyAction, treeNodeRowAction, treeNodeRowDoubleClickAction } from "@/lib/treeNodeClick";
+import {
+ objectSourceKindForTreeNode,
+ sidebarSelectionCopyAction,
+ treeNodeRowAction,
+ treeNodeRowDoubleClickAction,
+} from "@/lib/treeNodeClick";
import { formatCsv, formatJson, formatSqlInsert } from "@/lib/exportFormats";
import { fetchTableDataForExport } from "@/lib/tableDataExport";
import { buildCreateDatabaseSql, supportsCreateDatabaseCharset } from "@/lib/createDatabaseSql";
@@ -632,7 +637,8 @@ function buildDropObjectSql(): string {
function viewObjectSource() {
const node = props.node;
if (!node.connectionId || !node.database) return;
- const objectType = node.type === "procedure" ? "PROCEDURE" : "FUNCTION";
+ const objectType = objectSourceKindForTreeNode(node.type);
+ if (!objectType) return;
const schema = node.schema || node.database;
connectionStore
.ensureConnected(node.connectionId)
@@ -646,7 +652,7 @@ function viewObjectSource() {
queryStore.setObjectSource(tabId, {
schema,
name: node.label,
- objectType: objectType as "PROCEDURE" | "FUNCTION",
+ objectType,
});
})
.catch((e: any) => {
@@ -1819,6 +1825,9 @@ const isDragging = computed(() => dragState.active && dragState.draggedId === pr
{{ t("contextMenu.viewData") }}
+
+ {{ t("contextMenu.viewSource") }}
+
{{ t("contextMenu.editStructure") }}
diff --git a/apps/desktop/src/lib/treeNodeClick.ts b/apps/desktop/src/lib/treeNodeClick.ts
index c09d324926..2629d9aec2 100644
--- a/apps/desktop/src/lib/treeNodeClick.ts
+++ b/apps/desktop/src/lib/treeNodeClick.ts
@@ -1,4 +1,4 @@
-import type { TreeNodeType } from "@/types/database";
+import type { ObjectSourceKind, TreeNodeType } from "@/types/database";
import { matchesShortcut, type ShortcutLikeEvent } from "@/lib/keyboardShortcuts";
export type TreeNodeRowAction = "open-data" | "toggle" | "none";
@@ -18,6 +18,13 @@ const toggleLeafNodeTypes = new Set(["redis-db", "mongo-collection
const objectBrowserNodeTypes = new Set(["database", "schema", "object-browser"]);
const sourceNodeTypes = new Set(["procedure", "function"]);
+export function objectSourceKindForTreeNode(type: TreeNodeType): ObjectSourceKind | null {
+ if (type === "view") return "VIEW";
+ if (type === "procedure") return "PROCEDURE";
+ if (type === "function") return "FUNCTION";
+ return null;
+}
+
export function treeNodeRowAction(
type: TreeNodeType,
canExpand: boolean,
diff --git a/packages/app-tests/treeNodeClick.test.ts b/packages/app-tests/treeNodeClick.test.ts
index 31380f9832..931c2ce994 100644
--- a/packages/app-tests/treeNodeClick.test.ts
+++ b/packages/app-tests/treeNodeClick.test.ts
@@ -1,6 +1,11 @@
import test from "node:test";
import assert from "node:assert/strict";
-import { sidebarSelectionCopyAction, treeNodeRowAction, treeNodeRowDoubleClickAction } from "../../apps/desktop/src/lib/treeNodeClick.ts";
+import {
+ objectSourceKindForTreeNode,
+ sidebarSelectionCopyAction,
+ treeNodeRowAction,
+ treeNodeRowDoubleClickAction,
+} from "../../apps/desktop/src/lib/treeNodeClick.ts";
test("table and view rows open data without toggling structure groups", () => {
assert.equal(treeNodeRowAction("table", true), "open-data");
@@ -44,6 +49,13 @@ test("plain metadata leaf rows do nothing on row clicks", () => {
assert.equal(treeNodeRowAction("index", false), "none");
});
+test("maps source-capable sidebar nodes to object source kinds", () => {
+ assert.equal(objectSourceKindForTreeNode("view"), "VIEW");
+ assert.equal(objectSourceKindForTreeNode("procedure"), "PROCEDURE");
+ assert.equal(objectSourceKindForTreeNode("function"), "FUNCTION");
+ assert.equal(objectSourceKindForTreeNode("table"), null);
+});
+
test("database and schema rows open object browser only on double click", () => {
assert.equal(treeNodeRowAction("database", true), "toggle");
assert.equal(treeNodeRowAction("schema", true), "toggle");