mirror of
https://github.com/t8y2/dbx.git
synced 2026-10-29 16:18:55 +00:00
Merge pull request #140 from Bacon2994/codex/default-database
feat: 支持设置默认数据库
This commit is contained in:
@@ -57,6 +57,7 @@ import {
|
||||
import type { AiMessage } from "@/lib/api";
|
||||
import type { ConnectionConfig, QueryTab } from "@/types/database";
|
||||
import { useDatabaseOptions } from "@/composables/useDatabaseOptions";
|
||||
import { resolveDefaultDatabase } from "@/lib/defaultDatabase";
|
||||
|
||||
const { t } = useI18n();
|
||||
const settings = useSettingsStore();
|
||||
@@ -143,12 +144,16 @@ async function changeConnection(connectionId: string) {
|
||||
connectionStore.activeConnectionId = connectionId;
|
||||
const tab = props.tab;
|
||||
if (tab) {
|
||||
queryStore.updateConnection(tab.id, connectionId, conn.database || "");
|
||||
queryStore.updateConnection(tab.id, connectionId, resolveDefaultDatabase(conn, []));
|
||||
} else {
|
||||
queryStore.createTab(connectionId, conn.database || "");
|
||||
queryStore.createTab(connectionId, resolveDefaultDatabase(conn, []));
|
||||
}
|
||||
try {
|
||||
await loadDatabaseOptions(connectionId);
|
||||
const database = resolveDefaultDatabase(conn, allDbOptions.value[connectionId] || []);
|
||||
if (tab) {
|
||||
queryStore.updateDatabase(tab.id, database);
|
||||
}
|
||||
} catch (e: any) {
|
||||
toast(t("connection.connectFailed", { message: e?.message || String(e) }), 5000);
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ import {
|
||||
Loader2,
|
||||
Square,
|
||||
Database,
|
||||
Check,
|
||||
Table2,
|
||||
AlignLeft,
|
||||
GitBranch,
|
||||
@@ -21,6 +22,7 @@ import { useConnectionStore } from "@/stores/connectionStore";
|
||||
import { useDatabaseOptions } from "@/composables/useDatabaseOptions";
|
||||
import { useSchemaOptions } from "@/composables/useSchemaOptions";
|
||||
import { connectionIconType } from "@/lib/connectionPresentation";
|
||||
import { isDefaultDatabase } from "@/lib/defaultDatabase";
|
||||
import { connectionDisplayName } from "@/lib/tabPresentation";
|
||||
import type { QueryTab, ConnectionConfig } from "@/types/database";
|
||||
|
||||
@@ -40,6 +42,8 @@ const emit = defineEmits<{
|
||||
changeConnection: [connectionId: string];
|
||||
changeDatabase: [database: string];
|
||||
changeSchema: [schema: string | undefined];
|
||||
setDefaultDatabase: [];
|
||||
clearDefaultDatabase: [];
|
||||
}>();
|
||||
|
||||
const { t } = useI18n();
|
||||
@@ -67,6 +71,8 @@ const activeSchemaOptions = computed(() => {
|
||||
return getSchemaOptionsForDb(connection.id, props.activeTab.database);
|
||||
});
|
||||
|
||||
const isActiveDatabaseDefault = computed(() => isDefaultDatabase(props.activeConnection, activeDatabaseValue.value));
|
||||
|
||||
function databaseDisplayName(database: string): string {
|
||||
const connection = props.activeConnection;
|
||||
if (connection?.db_type === "redis" && database !== "") return `db${database}`;
|
||||
@@ -210,6 +216,16 @@ function databaseDisplayName(database: string): string {
|
||||
</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
<Button
|
||||
v-if="activeDatabaseValue"
|
||||
variant="ghost"
|
||||
size="sm"
|
||||
class="h-6 px-2 text-[11px]"
|
||||
@click="isActiveDatabaseDefault ? emit('clearDefaultDatabase') : emit('setDefaultDatabase')"
|
||||
>
|
||||
<Check v-if="isActiveDatabaseDefault" class="h-3 w-3" />
|
||||
{{ isActiveDatabaseDefault ? t("editor.defaultDatabase") : t("editor.setDefaultDatabase") }}
|
||||
</Button>
|
||||
</div>
|
||||
<div v-if="showSchemaSelector" class="flex items-center gap-1">
|
||||
<Layers class="h-3.5 w-3.5 shrink-0" />
|
||||
|
||||
@@ -51,8 +51,10 @@ import {
|
||||
import { useConnectionStore } from "@/stores/connectionStore";
|
||||
import { useQueryStore } from "@/stores/queryStore";
|
||||
import { useToast } from "@/composables/useToast";
|
||||
import { useDatabaseOptions } from "@/composables/useDatabaseOptions";
|
||||
import type { DatabaseType, QueryResult, TreeNode, TreeNodeType } from "@/types/database";
|
||||
import * as api from "@/lib/api";
|
||||
import { resolveDefaultDatabase } from "@/lib/defaultDatabase";
|
||||
import {
|
||||
DATABASE_EXPORT_PAGE_SIZE,
|
||||
DATABASE_EXPORT_ROW_LIMIT,
|
||||
@@ -80,12 +82,14 @@ import DatabaseIcon from "@/components/icons/DatabaseIcon.vue";
|
||||
import ConnectionErrorIndicator from "@/components/connection/ConnectionErrorIndicator.vue";
|
||||
import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogFooter } from "@/components/ui/dialog";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Badge } from "@/components/ui/badge";
|
||||
import { Input } from "@/components/ui/input";
|
||||
|
||||
const { t } = useI18n();
|
||||
const connectionStore = useConnectionStore();
|
||||
const queryStore = useQueryStore();
|
||||
const { toast } = useToast();
|
||||
const { getDatabaseOptions } = useDatabaseOptions();
|
||||
|
||||
const props = defineProps<{
|
||||
node: TreeNode;
|
||||
@@ -295,12 +299,39 @@ async function newQuery() {
|
||||
try {
|
||||
await connectionStore.ensureConnected(node.connectionId);
|
||||
connectionStore.activeConnectionId = node.connectionId;
|
||||
queryStore.createTab(node.connectionId, node.database || "", undefined, "query");
|
||||
if (node.database) {
|
||||
queryStore.createTab(node.connectionId, node.database, undefined, "query");
|
||||
return;
|
||||
}
|
||||
const connection = connectionStore.getConfig(node.connectionId);
|
||||
if (!connection) return;
|
||||
const options = await getDatabaseOptions(node.connectionId);
|
||||
queryStore.createTab(node.connectionId, resolveDefaultDatabase(connection, options), undefined, "query");
|
||||
} catch (e: any) {
|
||||
toast(t("connection.connectFailed", { message: e?.message || String(e) }), 5000);
|
||||
}
|
||||
}
|
||||
|
||||
async function setNodeAsDefaultDatabase() {
|
||||
const node = props.node;
|
||||
if (!node.connectionId || !node.database) return;
|
||||
try {
|
||||
await connectionStore.setDefaultDatabase(node.connectionId, node.database);
|
||||
} catch (e: any) {
|
||||
toast(t("connection.saveFailed", { message: e?.message || String(e) }), 5000);
|
||||
}
|
||||
}
|
||||
|
||||
async function clearNodeDefaultDatabase() {
|
||||
const node = props.node;
|
||||
if (!node.connectionId) return;
|
||||
try {
|
||||
await connectionStore.clearDefaultDatabase(node.connectionId);
|
||||
} catch (e: any) {
|
||||
toast(t("connection.saveFailed", { message: e?.message || String(e) }), 5000);
|
||||
}
|
||||
}
|
||||
|
||||
async function refresh() {
|
||||
const node = props.node;
|
||||
node.isExpanded = false;
|
||||
@@ -818,6 +849,13 @@ const canOpenFieldLineage = computed(() => {
|
||||
);
|
||||
});
|
||||
const isPinned = computed(() => props.node.pinned || connectionStore.isTreeNodePinned(props.node.id));
|
||||
const isNodeDefaultDatabase = computed(
|
||||
() =>
|
||||
(props.node.type === "database" || props.node.type === "redis-db" || props.node.type === "mongo-db") &&
|
||||
!!props.node.connectionId &&
|
||||
!!props.node.database &&
|
||||
connectionStore.isDefaultDatabase(props.node.connectionId, props.node.database),
|
||||
);
|
||||
const hasTypeMenu = computed(() => {
|
||||
const t = props.node.type;
|
||||
return (
|
||||
@@ -1047,6 +1085,9 @@ const isDragging = computed(() => dragState.active && dragState.draggedId === pr
|
||||
@vue:mounted="($event: any) => $event.el.focus()"
|
||||
/>
|
||||
<span v-else class="min-w-0 flex-1 truncate">{{ isGroupLabel(node) ? t(node.label) : node.label }}</span>
|
||||
<Badge v-if="isNodeDefaultDatabase" variant="secondary" class="h-4 px-1.5 text-[10px]">
|
||||
{{ t("editor.defaultDatabase") }}
|
||||
</Badge>
|
||||
<span v-if="columnComment" class="truncate text-muted-foreground/60 text-[10px] max-w-[40%]">{{
|
||||
columnComment
|
||||
}}</span>
|
||||
@@ -1165,6 +1206,12 @@ const isDragging = computed(() => dragState.active && dragState.draggedId === pr
|
||||
<ContextMenuItem @click="newQuery">
|
||||
<TerminalSquare class="w-4 h-4" /> {{ t("contextMenu.newQuery") }}
|
||||
</ContextMenuItem>
|
||||
<ContextMenuItem v-if="node.type === 'database' && !isNodeDefaultDatabase" @click="setNodeAsDefaultDatabase">
|
||||
<Database class="w-4 h-4" /> {{ t("contextMenu.setDefaultDatabase") }}
|
||||
</ContextMenuItem>
|
||||
<ContextMenuItem v-if="node.type === 'database' && isNodeDefaultDatabase" @click="clearNodeDefaultDatabase">
|
||||
<Database class="w-4 h-4" /> {{ t("contextMenu.clearDefaultDatabase") }}
|
||||
</ContextMenuItem>
|
||||
<ContextMenuItem v-if="canCreateTable" @click="createTable">
|
||||
<Plus class="w-4 h-4" /> {{ t("contextMenu.createTable") }}
|
||||
</ContextMenuItem>
|
||||
@@ -1194,6 +1241,18 @@ const isDragging = computed(() => dragState.active && dragState.draggedId === pr
|
||||
</ContextMenuItem>
|
||||
</template>
|
||||
|
||||
<template v-if="node.type === 'redis-db' || node.type === 'mongo-db'">
|
||||
<ContextMenuItem @click="newQuery">
|
||||
<TerminalSquare class="w-4 h-4" /> {{ t("contextMenu.newQuery") }}
|
||||
</ContextMenuItem>
|
||||
<ContextMenuItem v-if="!isNodeDefaultDatabase" @click="setNodeAsDefaultDatabase">
|
||||
<Database class="w-4 h-4" /> {{ t("contextMenu.setDefaultDatabase") }}
|
||||
</ContextMenuItem>
|
||||
<ContextMenuItem v-if="isNodeDefaultDatabase" @click="clearNodeDefaultDatabase">
|
||||
<Database class="w-4 h-4" /> {{ t("contextMenu.clearDefaultDatabase") }}
|
||||
</ContextMenuItem>
|
||||
</template>
|
||||
|
||||
<template v-if="node.type === 'table' || node.type === 'view'">
|
||||
<ContextMenuItem @click="openData">
|
||||
<TableProperties class="w-4 h-4" /> {{ t("contextMenu.viewData") }}
|
||||
|
||||
Reference in New Issue
Block a user