feat(sidebar): add routine source open mode
This commit is contained in:
1 parent
2152f8cde8
commit
d928412bf6
16 files changed
+161
-6
No files matched your search
@@ -375,6 +375,7 @@ const editingShortcutId = ref<ShortcutActionId | null>(null);
|
||||
const editSidebarActivation = ref(settingsStore.editorSettings.sidebarActivation);
|
||||
const editSidebarObjectDisplay = ref(settingsStore.editorSettings.sidebarObjectDisplay);
|
||||
const sidebarObjectDisplayHelp = ref<"grouped" | "simple" | null>(null);
|
||||
const editRoutineSourceOpenMode = ref(settingsStore.editorSettings.routineSourceOpenMode);
|
||||
const editSidebarTableSearchEnabled = ref(settingsStore.editorSettings.sidebarTableSearchEnabled);
|
||||
const editAutoSelectActiveSidebarNode = ref(settingsStore.editorSettings.autoSelectActiveSidebarNode);
|
||||
const editOpenTabsRestoreMode = ref<OpenTabsRestoreMode>(settingsStore.editorSettings.openTabsRestoreMode);
|
||||
@@ -478,6 +479,7 @@ function currentEditorSettingsDraft(): EditorSettingsDraft {
|
||||
sqlFormatter: normalizeSqlFormatterSettings(editSqlFormatter.value),
|
||||
sidebarActivation: editSidebarActivation.value,
|
||||
sidebarObjectDisplay: editSidebarObjectDisplay.value,
|
||||
routineSourceOpenMode: editRoutineSourceOpenMode.value,
|
||||
sidebarTableSearchEnabled: editSidebarTableSearchEnabled.value,
|
||||
autoSelectActiveSidebarNode: editAutoSelectActiveSidebarNode.value,
|
||||
openTabsRestoreMode: editOpenTabsRestoreMode.value,
|
||||
@@ -742,6 +744,7 @@ function syncEditorSettingsDraftFromStore() {
|
||||
sqlFormatterConfigValid.value = true;
|
||||
editSidebarActivation.value = settingsStore.editorSettings.sidebarActivation;
|
||||
editSidebarObjectDisplay.value = settingsStore.editorSettings.sidebarObjectDisplay;
|
||||
editRoutineSourceOpenMode.value = settingsStore.editorSettings.routineSourceOpenMode;
|
||||
editSidebarTableSearchEnabled.value = settingsStore.editorSettings.sidebarTableSearchEnabled;
|
||||
editAutoSelectActiveSidebarNode.value = settingsStore.editorSettings.autoSelectActiveSidebarNode;
|
||||
editOpenTabsRestoreMode.value = settingsStore.editorSettings.openTabsRestoreMode;
|
||||
@@ -944,6 +947,7 @@ function resetDefaultsForTab(tab: SettingsCategory) {
|
||||
editSidebarTablePageSize.value = DEFAULT_SIDEBAR_TABLE_PAGE_SIZE;
|
||||
editSidebarActivation.value = DEFAULT_EDITOR_SETTINGS.sidebarActivation;
|
||||
editSidebarObjectDisplay.value = DEFAULT_EDITOR_SETTINGS.sidebarObjectDisplay;
|
||||
editRoutineSourceOpenMode.value = DEFAULT_EDITOR_SETTINGS.routineSourceOpenMode;
|
||||
editSidebarTableSearchEnabled.value = DEFAULT_EDITOR_SETTINGS.sidebarTableSearchEnabled;
|
||||
editAutoSelectActiveSidebarNode.value = DEFAULT_EDITOR_SETTINGS.autoSelectActiveSidebarNode;
|
||||
editOpenTabsRestoreMode.value = DEFAULT_EDITOR_SETTINGS.openTabsRestoreMode;
|
||||
@@ -1032,6 +1036,7 @@ function resetAllDefaults() {
|
||||
sqlFormatterConfigValid.value = true;
|
||||
editSidebarActivation.value = DEFAULT_EDITOR_SETTINGS.sidebarActivation;
|
||||
editSidebarObjectDisplay.value = DEFAULT_EDITOR_SETTINGS.sidebarObjectDisplay;
|
||||
editRoutineSourceOpenMode.value = DEFAULT_EDITOR_SETTINGS.routineSourceOpenMode;
|
||||
editSidebarTableSearchEnabled.value = DEFAULT_EDITOR_SETTINGS.sidebarTableSearchEnabled;
|
||||
editAutoSelectActiveSidebarNode.value = DEFAULT_EDITOR_SETTINGS.autoSelectActiveSidebarNode;
|
||||
editOpenTabsRestoreMode.value = DEFAULT_EDITOR_SETTINGS.openTabsRestoreMode;
|
||||
@@ -1256,6 +1261,10 @@ function setSidebarObjectDisplay(value: "grouped" | "simple") {
|
||||
editSidebarObjectDisplay.value = value;
|
||||
}
|
||||
|
||||
function setRoutineSourceOpenMode(value: "query-tab" | "dialog") {
|
||||
editRoutineSourceOpenMode.value = value;
|
||||
}
|
||||
|
||||
function setIconTheme(value: DesktopIconTheme) {
|
||||
editIconTheme.value = value;
|
||||
}
|
||||
@@ -4098,6 +4107,32 @@ onUnmounted(cleanupPreviewEditor);
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="space-y-2">
|
||||
<div class="flex items-center gap-2">
|
||||
<Label>{{ t("settings.routineSourceOpenMode") }}</Label>
|
||||
<HelpTooltip :label="t('settings.routineSourceOpenMode')">
|
||||
{{ t("settings.routineSourceOpenModeQueryTabDescription") }}
|
||||
</HelpTooltip>
|
||||
</div>
|
||||
<div class="grid grid-cols-2 gap-2">
|
||||
<Button type="button" variant="outline" class="h-auto justify-start border p-3" :class="editRoutineSourceOpenMode === 'query-tab' ? 'dbx-choice-selected' : ''" @click="setRoutineSourceOpenMode('query-tab')">
|
||||
<div class="text-left">
|
||||
<div class="text-sm font-medium">{{ t("settings.routineSourceOpenModeQueryTab") }}</div>
|
||||
<div class="text-xs text-muted-foreground">
|
||||
{{ t("settings.routineSourceOpenModeQueryTabDescription") }}
|
||||
</div>
|
||||
</div>
|
||||
</Button>
|
||||
<Button type="button" variant="outline" class="h-auto justify-start border p-3" :class="editRoutineSourceOpenMode === 'dialog' ? 'dbx-choice-selected' : ''" @click="setRoutineSourceOpenMode('dialog')">
|
||||
<div class="text-left">
|
||||
<div class="text-sm font-medium">{{ t("settings.routineSourceOpenModeDialog") }}</div>
|
||||
<div class="text-xs text-muted-foreground">
|
||||
{{ t("settings.routineSourceOpenModeDialogDescription") }}
|
||||
</div>
|
||||
</div>
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex items-center justify-between gap-4 rounded-md border bg-muted/20 px-3 py-2">
|
||||
<div class="flex items-center gap-2">
|
||||
<Label for="sidebar-table-search-enabled">{{ t("settings.sidebarTableSearchEnabled") }}</Label>
|
||||
|
||||
@@ -22,6 +22,7 @@ const emit = defineEmits<{
|
||||
export: [];
|
||||
startResize: [event: MouseEvent];
|
||||
collapse: [];
|
||||
"open-settings": [initialTab: string];
|
||||
}>();
|
||||
|
||||
type ImportSource = "dbx" | "navicat" | "dbeaver" | "datagrip";
|
||||
@@ -243,7 +244,7 @@ defineExpose({ focusSearch });
|
||||
</template>
|
||||
</div>
|
||||
<div class="flex-1 min-h-0">
|
||||
<ConnectionTree ref="connectionTreeRef" />
|
||||
<ConnectionTree ref="connectionTreeRef" @open-settings="(initialTab) => emit('open-settings', initialTab)" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="panel-resize-handle panel-resize-handle--right" @mousedown="emit('startResize', $event)" />
|
||||
|
||||
@@ -62,6 +62,10 @@ const sidebarScrollbarTrackRef = ref<HTMLElement | null>(null);
|
||||
const sidebarHorizontalScrollbarTrackRef = ref<HTMLElement | null>(null);
|
||||
const sidebarContextMenuRef = ref<{ close: () => void } | null>(null);
|
||||
const sidebarContextMenuItems = ref<ContextMenuItem[]>([]);
|
||||
const emit = defineEmits<{
|
||||
"open-settings": [initialTab: string];
|
||||
}>();
|
||||
|
||||
const sidebarContextMenuTarget = ref<SidebarActionTarget | null>(null);
|
||||
const sidebarDangerDialogRequest = ref<SidebarDangerDialogRequest | null>(null);
|
||||
const sidebarDangerDialogOpen = ref(false);
|
||||
@@ -1219,6 +1223,10 @@ function openSidebarObjectSource(node: TreeNode, initialEditing: boolean) {
|
||||
});
|
||||
}
|
||||
|
||||
function openSidebarSettings(initialTab: string) {
|
||||
emit("open-settings", initialTab);
|
||||
}
|
||||
|
||||
function openSidebarProcedure(node: TreeNode) {
|
||||
if (node.type !== "procedure" || !node.connectionId || !node.database) return;
|
||||
beginSidebarAction();
|
||||
@@ -1605,6 +1613,7 @@ defineExpose({ focusSearch, createNewGroup, collapseAllTreeNodes });
|
||||
@open-ddl="openSidebarDdl"
|
||||
@open-object-source="openSidebarObjectSource"
|
||||
@open-procedure="openSidebarProcedure"
|
||||
@open-settings="openSidebarSettings"
|
||||
@open-data="openSidebarData"
|
||||
@open-visible-databases="openSidebarVisibleDatabases"
|
||||
@open-visible-schemas="openSidebarVisibleSchemas"
|
||||
|
||||
@@ -52,6 +52,7 @@ import {
|
||||
ListX,
|
||||
Info,
|
||||
X,
|
||||
Settings2,
|
||||
} from "@lucide/vue";
|
||||
import type { ContextMenuItem } from "@/components/ui/CustomContextMenu.vue";
|
||||
import { CONNECTION_ATTEMPT_CANCELLED_MESSAGE, useConnectionStore } from "@/stores/connectionStore";
|
||||
@@ -316,6 +317,7 @@ const emit = defineEmits<{
|
||||
"open-ddl": [node: TreeNode];
|
||||
"open-object-source": [node: TreeNode, initialEditing: boolean];
|
||||
"open-procedure": [node: TreeNode];
|
||||
"open-settings": [initialTab: string];
|
||||
"open-data": [node: TreeNode, requireSelection: boolean, openMode: DataTabOpenMode, runner: (node: TreeNode, request: SidebarDataOpenRequest) => Promise<void>];
|
||||
"open-visible-databases": [node: TreeNode];
|
||||
"open-visible-schemas": [node: TreeNode];
|
||||
@@ -1508,12 +1510,38 @@ async function refreshDropTableChildObjectPreviewSql() {
|
||||
function openObjectSourceDialog(initialEditing: boolean) {
|
||||
const node = activeNode.value;
|
||||
if (!node.connectionId || !node.database) return;
|
||||
const connectionId = node.connectionId;
|
||||
const database = node.database;
|
||||
const objectType = objectSourceKindForTreeNode(node.type);
|
||||
if (!objectType) return;
|
||||
const openMode = settingsStore.editorSettings.routineSourceOpenMode;
|
||||
if (openMode === "query-tab") {
|
||||
void connectionStore
|
||||
.ensureConnected(connectionId)
|
||||
.then(async () => {
|
||||
connectionStore.activeConnectionId = connectionId;
|
||||
const schema = node.schema || database;
|
||||
const result = await api.getObjectSource(connectionId, database, schema, node.objectName || node.label, objectType as any, node.signature);
|
||||
const tabId = queryStore.createTab(connectionId, database, `Source - ${node.label}`, "query", schema, result.source, node.catalog, { forceNew: true });
|
||||
const sourceIsEditable = result.editable !== false && !["SEQUENCE", "TRIGGER", "TYPE", "TYPE_BODY"].includes(objectType);
|
||||
if (sourceIsEditable) {
|
||||
queryStore.setObjectSource(tabId, {
|
||||
schema,
|
||||
name: node.objectName || node.label,
|
||||
objectType,
|
||||
signature: node.signature,
|
||||
});
|
||||
}
|
||||
})
|
||||
.catch((e: any) => {
|
||||
toast(e?.message || String(e), 5000);
|
||||
});
|
||||
return;
|
||||
}
|
||||
void connectionStore
|
||||
.ensureConnected(node.connectionId)
|
||||
.ensureConnected(connectionId)
|
||||
.then(() => {
|
||||
connectionStore.activeConnectionId = node.connectionId!;
|
||||
connectionStore.activeConnectionId = connectionId;
|
||||
emit("open-object-source", node, initialEditing);
|
||||
})
|
||||
.catch((e: any) => {
|
||||
@@ -4150,6 +4178,7 @@ function buildObjectSidebarMenu(context: SidebarMenuFactoryContext): boolean {
|
||||
action: () => emit("open-ddl", node),
|
||||
icon: FileCode,
|
||||
});
|
||||
items.push({ label: t("contextMenu.changeOpenMode"), action: () => emit("open-settings", "navigation"), icon: Settings2 });
|
||||
}
|
||||
if (canOpenStructureEditor.value) {
|
||||
items.push({ label: t("contextMenu.editStructure"), action: openStructureEditor, icon: PencilRuler });
|
||||
@@ -4314,6 +4343,8 @@ function buildObjectSidebarMenu(context: SidebarMenuFactoryContext): boolean {
|
||||
});
|
||||
}
|
||||
items.push({ label: "", separator: true });
|
||||
items.push({ label: t("contextMenu.changeOpenMode"), action: () => emit("open-settings", "navigation"), icon: Settings2 });
|
||||
items.push({ label: "", separator: true });
|
||||
items.push({
|
||||
label: deleteMenuLabel(node.type === "procedure" ? t("contextMenu.dropProcedure") : t("contextMenu.dropFunction")),
|
||||
action: deleteMenuAction(requestDropObject),
|
||||
@@ -4326,15 +4357,15 @@ function buildObjectSidebarMenu(context: SidebarMenuFactoryContext): boolean {
|
||||
|
||||
if (node.type === "sequence") {
|
||||
items.push({ label: t("contextMenu.viewSource"), action: () => openObjectSourceDialog(false), icon: Code2 });
|
||||
items.push({ label: "", separator: true });
|
||||
items.push({ label: t("contextMenu.copyName"), action: copyName, icon: Copy, shortcut: shortcutCopyName.value });
|
||||
items.push({ label: t("contextMenu.changeOpenMode"), action: () => emit("open-settings", "navigation"), icon: Settings2 });
|
||||
return true;
|
||||
}
|
||||
|
||||
if (node.type === "trigger" || node.type === "package" || node.type === "package-body" || node.type === "type" || node.type === "type-body") {
|
||||
items.push({ label: t("contextMenu.viewSource"), action: () => openObjectSourceDialog(false), icon: Code2 });
|
||||
items.push({ label: "", separator: true });
|
||||
items.push({ label: t("contextMenu.copyName"), action: copyName, icon: Copy, shortcut: shortcutCopyName.value });
|
||||
items.push({ label: t("contextMenu.changeOpenMode"), action: () => emit("open-settings", "navigation"), icon: Settings2 });
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
||||
Reference in new issue
Block a user