fix(postgresql): show trigger source details
This commit is contained in:
13 files changed
+137
-19
No files matched your search
@@ -22,6 +22,7 @@ const props = withDefaults(
|
||||
database: string;
|
||||
schema?: string;
|
||||
name: string;
|
||||
relationName?: string;
|
||||
signature?: string;
|
||||
objectType: ObjectSourceKind;
|
||||
databaseType?: DatabaseType;
|
||||
@@ -59,7 +60,7 @@ const canEdit = computed(() => sourceEditable.value && props.objectType !== "SEQ
|
||||
const title = computed(() => `${editing.value ? t("contextMenu.editView") : t("contextMenu.viewSource")} - ${props.name}`);
|
||||
|
||||
watch(
|
||||
() => [props.open, props.connectionId, props.database, props.schema, props.name, props.signature, props.objectType, props.initialEditing] as const,
|
||||
() => [props.open, props.connectionId, props.database, props.schema, props.name, props.relationName, props.signature, props.objectType, props.initialEditing] as const,
|
||||
() => {
|
||||
if (props.open) void loadSource();
|
||||
},
|
||||
@@ -79,7 +80,7 @@ async function loadSource(nextEditing = props.initialEditing && canEdit.value) {
|
||||
try {
|
||||
if (!props.databaseType) throw new Error("Connection type is unavailable.");
|
||||
const schema = props.schema || props.database;
|
||||
const result = await api.getObjectSource(props.connectionId, props.database, schema, props.name, props.objectType, props.signature);
|
||||
const result = await api.getObjectSource(props.connectionId, props.database, schema, props.name, props.objectType, props.signature, props.relationName);
|
||||
const editableAllowed = result.editable !== false;
|
||||
const editable = await buildEditableObjectSource({
|
||||
databaseType: props.databaseType,
|
||||
|
||||
@@ -1552,6 +1552,7 @@ defineExpose({ focusSearch, createNewGroup, collapseAllTreeNodes });
|
||||
:database="sidebarObjectSourceTarget.node.database!"
|
||||
:schema="sidebarObjectSourceTarget.node.schema"
|
||||
:name="sidebarObjectSourceTarget.node.objectName || sidebarObjectSourceTarget.node.label"
|
||||
:relation-name="sidebarObjectSourceTarget.node.tableName"
|
||||
:signature="sidebarObjectSourceTarget.node.signature"
|
||||
:object-type="sidebarObjectSourceType"
|
||||
:database-type="sidebarObjectSourceDatabaseType"
|
||||
|
||||
@@ -681,10 +681,10 @@ function runRowClickAction(clickDetail: number) {
|
||||
if (!shouldRunTreeNodeRowAction(action, clickDetail)) return;
|
||||
if (action === "open-data") {
|
||||
scheduleOpenData(node);
|
||||
} else if (action === "open-source") {
|
||||
openObjectSourceDialog(false);
|
||||
} else if (isDocumentBrowserTreeNode(node.type)) {
|
||||
openMongoTreeData(node);
|
||||
} else if (node.type === "procedure" || node.type === "function" || node.type === "trigger" || node.type === "sequence" || node.type === "package" || node.type === "package-body" || node.type === "type" || node.type === "type-body") {
|
||||
openObjectSourceDialog(false);
|
||||
} else if (action === "toggle") {
|
||||
toggle();
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { createPinia, setActivePinia } from "pinia";
|
||||
import { beforeEach, describe, expect, it, vi } from "vitest";
|
||||
import { loadSidebarObjectGroup } from "@/lib/sidebar/sidebarObjectGroupRouting";
|
||||
import type { ConnectionConfig, ObjectInfo, TreeNode } from "@/types/database";
|
||||
import type { ConnectionConfig, ObjectInfo, TreeNode, TriggerInfo } from "@/types/database";
|
||||
|
||||
function installLocalStorage() {
|
||||
const data = new Map<string, string>();
|
||||
@@ -92,7 +92,13 @@ describe("sidebar object-group routing", () => {
|
||||
|
||||
it("keeps table-level trigger groups on listTriggers", async () => {
|
||||
const listObjects = vi.fn<() => Promise<ObjectInfo[]>>().mockResolvedValue([]);
|
||||
const listTriggers = vi.fn<() => Promise<never[]>>().mockResolvedValue([]);
|
||||
const listTriggers = vi.fn<() => Promise<TriggerInfo[]>>().mockResolvedValue([
|
||||
{
|
||||
name: "trg_orders_audit",
|
||||
timing: "AFTER",
|
||||
event: "UPDATE",
|
||||
},
|
||||
]);
|
||||
const { connection, store } = await createStore({ listObjects, listTriggers });
|
||||
const tableTriggerGroup: TreeNode = {
|
||||
...objectGroup("group-triggers", `${connection.id}:app:app:orders:__triggers`),
|
||||
@@ -105,7 +111,18 @@ describe("sidebar object-group routing", () => {
|
||||
|
||||
expect(listTriggers).toHaveBeenCalledWith(connection.id, "app", "app", "orders", undefined);
|
||||
expect(listObjects).not.toHaveBeenCalled();
|
||||
expect(storedTriggerGroup).toMatchObject({ isExpanded: true, isLoading: false, children: [] });
|
||||
expect(storedTriggerGroup).toMatchObject({
|
||||
isExpanded: true,
|
||||
isLoading: false,
|
||||
children: [
|
||||
{
|
||||
label: "trg_orders_audit (AFTER UPDATE)",
|
||||
objectName: "trg_orders_audit",
|
||||
tableName: "orders",
|
||||
type: "trigger",
|
||||
},
|
||||
],
|
||||
});
|
||||
});
|
||||
|
||||
it("propagates rejected schema-level metadata while clearing the loading state", async () => {
|
||||
|
||||
@@ -656,8 +656,8 @@ export async function completionAssistantSearch(request: CompletionAssistantRequ
|
||||
return post("/api/schema/completion-assistant", request);
|
||||
}
|
||||
|
||||
export async function getObjectSource(connectionId: string, database: string, schema: string, name: string, objectType: ObjectSourceKind, signature?: string): Promise<ObjectSource> {
|
||||
return get(`/api/schema/object-source?${qs({ connection_id: connectionId, database, schema, table: name, object_type: objectType, signature })}`);
|
||||
export async function getObjectSource(connectionId: string, database: string, schema: string, name: string, objectType: ObjectSourceKind, signature?: string, relationName?: string): Promise<ObjectSource> {
|
||||
return get(`/api/schema/object-source?${qs({ connection_id: connectionId, database, schema, table: name, object_type: objectType, signature, relation_name: relationName })}`);
|
||||
}
|
||||
|
||||
export async function getColumns(connectionId: string, database: string, schema: string, table: string, catalog?: string, clientSessionId?: string): Promise<ColumnInfo[]> {
|
||||
|
||||
@@ -832,8 +832,8 @@ export async function completionAssistantSearch(request: CompletionAssistantRequ
|
||||
return invoke("completion_assistant_search", { request });
|
||||
}
|
||||
|
||||
export async function getObjectSource(connectionId: string, database: string, schema: string, name: string, objectType: ObjectSourceKind, signature?: string): Promise<ObjectSource> {
|
||||
return invoke("get_object_source", { connectionId, database, schema, name, objectType, signature });
|
||||
export async function getObjectSource(connectionId: string, database: string, schema: string, name: string, objectType: ObjectSourceKind, signature?: string, relationName?: string): Promise<ObjectSource> {
|
||||
return invoke("get_object_source", { connectionId, database, schema, name, objectType, signature, relationName });
|
||||
}
|
||||
|
||||
export async function listSchemas(connectionId: string, database: string, applyVisibleFilter = false): Promise<string[]> {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import type { ObjectSourceKind, TreeNode, TreeNodeType } from "@/types/database";
|
||||
import { matchesShortcut, type ShortcutLikeEvent } from "@/lib/editor/keyboardShortcuts";
|
||||
|
||||
export type TreeNodeRowAction = "open-data" | "toggle" | "none";
|
||||
export type TreeNodeRowAction = "open-data" | "open-source" | "toggle" | "none";
|
||||
export type TreeNodeRowDoubleClickAction = "open-data" | "activate-data" | "open-object-browser" | "open-object-browser-and-expand" | "open-source" | "open-saved-sql" | "toggle" | "none";
|
||||
export type SidebarSelectionCopyAction = "copy-name" | "none";
|
||||
export type SidebarActivation = "single" | "double";
|
||||
@@ -36,6 +36,7 @@ export function isDocumentBrowserTreeNode(type: TreeNodeType): boolean {
|
||||
export function treeNodeRowAction(type: TreeNodeType, canExpand: boolean, activation: SidebarActivation = "single"): TreeNodeRowAction {
|
||||
if (activation === "double") return "none";
|
||||
if (dataNodeTypes.has(type)) return "open-data";
|
||||
if (sourceNodeTypes.has(type)) return "open-source";
|
||||
if (toggleLeafNodeTypes.has(type)) return "toggle";
|
||||
if (canExpand) return "toggle";
|
||||
return "none";
|
||||
|
||||
@@ -4013,6 +4013,7 @@ export const useConnectionStore = defineStore("connection", () => {
|
||||
triggers.map((tr) => ({
|
||||
id: `${parentId}:${tr.name}`,
|
||||
label: `${tr.name} (${tr.timing} ${tr.event})`,
|
||||
objectName: tr.name,
|
||||
type: "trigger" as const,
|
||||
connectionId,
|
||||
database,
|
||||
|
||||
Reference in new issue
Block a user