fix(connection): share connection group path map

This commit is contained in:
vrustx authored and GitHub committed 2026-07-15 19:29:38 +08:00
1 parent 8311a88b07
commit 1c34b2b568
12 files changed
+114 -15

No files matched your search

@@ -0,0 +1,13 @@
<script setup lang="ts">
import { useConnectionGroupLabel } from "@/composables/useConnectionGroupLabel";
const props = defineProps<{ connectionId: string }>();
const { connectionGroupLabel } = useConnectionGroupLabel();
</script>
<template>
<span class="min-w-0 max-w-28 shrink-0 truncate rounded-sm bg-muted/70 px-1.5 py-0.5 text-[10px] leading-none text-muted-foreground" :title="connectionGroupLabel(props.connectionId)">
{{ connectionGroupLabel(props.connectionId) }}
</span>
</template>
@@ -8,6 +8,7 @@ import { Input } from "@/components/ui/input";
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
import { useConnectionStore } from "@/stores/connectionStore";
import DatabaseIcon from "@/components/icons/DatabaseIcon.vue";
import ConnectionGroupBadge from "@/components/connection/ConnectionGroupBadge.vue";
import * as api from "@/lib/backend/api";
import { DIAGRAM_SQL_TYPES, isSchemaAware as isSchemaAwareDatabase } from "@/lib/database/databaseCapabilities";
import { databaseOptionsForConnection } from "@/composables/useDatabaseOptions";
@@ -814,9 +815,10 @@ onUnmounted(stopDrag);
</SelectTrigger>
<SelectContent>
<SelectItem v-for="connection in sqlConnections" :key="connection.id" :value="connection.id">
<div class="flex items-center gap-2">
<DatabaseIcon :db-type="connection.driver_profile || connection.db_type" class="w-3.5 h-3.5" />
{{ connection.name }}
<div class="flex min-w-0 items-center gap-2">
<DatabaseIcon :db-type="connection.driver_profile || connection.db_type" class="w-3.5 h-3.5 shrink-0" />
<ConnectionGroupBadge :connection-id="connection.id" />
<span class="min-w-0 flex-1 truncate">{{ connection.name }}</span>
</div>
</SelectItem>
</SelectContent>
@@ -7,6 +7,7 @@ import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
import SearchableSelect from "@/components/ui/searchable-select/SearchableSelect.vue";
import ConnectionGroupBadge from "@/components/connection/ConnectionGroupBadge.vue";
import { useConnectionStore } from "@/stores/connectionStore";
import { useToast } from "@/composables/useToast";
import { databaseOptionsForConnection } from "@/composables/useDatabaseOptions";
@@ -915,6 +916,7 @@ watch(
<template #option-label="{ option, label }">
<div class="flex min-w-0 items-center gap-2">
<DatabaseIcon :db-type="connectionIconType(option)" class="h-3.5 w-3.5 shrink-0" />
<ConnectionGroupBadge :connection-id="option" />
<span class="min-w-0 flex-1 truncate">{{ label }}</span>
</div>
</template>
@@ -1001,6 +1003,7 @@ watch(
<template #option-label="{ option, label }">
<div class="flex min-w-0 items-center gap-2">
<DatabaseIcon :db-type="connectionIconType(option)" class="h-3.5 w-3.5 shrink-0" />
<ConnectionGroupBadge :connection-id="option" />
<span class="min-w-0 flex-1 truncate">{{ label }}</span>
</div>
</template>
@@ -5,6 +5,7 @@ import { Label } from "@/components/ui/label";
import { Button } from "@/components/ui/button";
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
import SearchableSelect from "@/components/ui/searchable-select/SearchableSelect.vue";
import ConnectionGroupBadge from "@/components/connection/ConnectionGroupBadge.vue";
import { useConnectionStore } from "@/stores/connectionStore";
import DatabaseIcon from "@/components/icons/DatabaseIcon.vue";
import * as api from "@/lib/backend/api";
@@ -269,6 +270,7 @@ async function fetchDbVersion(connectionId: string, database: string, schema: st
<template #option-label="{ option, label }">
<div class="flex min-w-0 items-center gap-2">
<DatabaseIcon :db-type="sqlConnections.find((c) => c.id === option)?.driver_profile || sqlConnections.find((c) => c.id === option)?.db_type || 'mysql'" class="h-3.5 w-3.5 shrink-0" />
<ConnectionGroupBadge :connection-id="option" />
<span class="min-w-0 flex-1 truncate">{{ label }}</span>
</div>
</template>
@@ -353,6 +355,7 @@ async function fetchDbVersion(connectionId: string, database: string, schema: st
<template #option-label="{ option, label }">
<div class="flex min-w-0 items-center gap-2">
<DatabaseIcon :db-type="sqlConnections.find((c) => c.id === option)?.driver_profile || sqlConnections.find((c) => c.id === option)?.db_type || 'mysql'" class="h-3.5 w-3.5 shrink-0" />
<ConnectionGroupBadge :connection-id="option" />
<span class="min-w-0 flex-1 truncate">{{ label }}</span>
</div>
</template>
@@ -50,6 +50,7 @@ import { useConnectionStore } from "@/stores/connectionStore";
import { useSavedSqlStore } from "@/stores/savedSqlStore";
import { connectionIconType } from "@/lib/connection/connectionPresentation";
import DatabaseIcon from "@/components/icons/DatabaseIcon.vue";
import ConnectionGroupBadge from "@/components/connection/ConnectionGroupBadge.vue";
import { useQueryStore } from "@/stores/queryStore";
import { useToast } from "@/composables/useToast";
import { useNavigationTargets } from "@/composables/useNavigationTargets";
@@ -1995,6 +1996,7 @@ async function openExternalUrl(url: string) {
<SelectItem v-for="conn in connectionStore.connections" :key="conn.id" :value="conn.id">
<div class="flex min-w-0 items-center gap-2">
<DatabaseIcon :db-type="connectionIconType(conn)" class="h-3.5 w-3.5 shrink-0" />
<ConnectionGroupBadge :connection-id="conn.id" />
<span class="truncate">{{ conn.name }}</span>
</div>
</SelectItem>
@@ -7,6 +7,7 @@ import { Label } from "@/components/ui/label";
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
import { useConnectionStore } from "@/stores/connectionStore";
import DatabaseIcon from "@/components/icons/DatabaseIcon.vue";
import ConnectionGroupBadge from "@/components/connection/ConnectionGroupBadge.vue";
import * as api from "@/lib/backend/api";
import type { ExportProgress } from "@/lib/backend/api";
import { isSchemaAware } from "@/lib/database/databaseFeatureSupport";
@@ -572,9 +573,10 @@ watch(
</SelectTrigger>
<SelectContent position="popper" align="start">
<SelectItem v-for="c in sqlConnections" :key="c.id" :value="c.id">
<div class="flex items-center gap-2">
<DatabaseIcon :db-type="c.driver_profile || c.db_type" class="w-3.5 h-3.5" />
{{ c.name }}
<div class="flex min-w-0 items-center gap-2">
<DatabaseIcon :db-type="c.driver_profile || c.db_type" class="w-3.5 h-3.5 shrink-0" />
<ConnectionGroupBadge :connection-id="c.id" />
<span class="min-w-0 flex-1 truncate">{{ c.name }}</span>
</div>
</SelectItem>
</SelectContent>
@@ -14,7 +14,7 @@ import { useSchemaOptions } from "@/composables/useSchemaOptions";
import { connectionIconType } from "@/lib/connection/connectionPresentation";
import { formatDatabaseLabel, isDefaultDatabase } from "@/lib/database/defaultDatabase";
import { connectionDisplayName } from "@/lib/tabs/tabPresentation";
import { buildConnectionGroupPathMap } from "@/lib/sidebar/sidebarLayout";
import { useConnectionGroupLabel } from "@/composables/useConnectionGroupLabel";
import { isSingleDatabase, supportsClearableQuerySchema, supportsSqlInListPaste, supportsTransaction as supportsTransactionFeature } from "@/lib/database/databaseCapabilities";
import { hexToRgba } from "@/lib/common/color";
import { productionContextForDatabase } from "@/lib/database/productionSafety";
@@ -67,7 +67,7 @@ const activeDatabaseOptions = computed(() => {
});
const connectionOptionIds = computed(() => connectionStore.connections.map((connection) => connection.id));
const connectionGroupPaths = computed(() => buildConnectionGroupPathMap(connectionStore.sidebarLayout));
const { connectionGroupLabel } = useConnectionGroupLabel();
const activeDatabaseValue = computed(() => props.activeTab.database || "");
const activeProductionContext = computed(() => productionContextForDatabase(props.activeConnection, props.activeTab.database));
const showConnectionProductionBadge = computed(() => activeProductionContext.value.reason === "connection");
@@ -156,10 +156,6 @@ function connectionById(connectionId: string): ConnectionConfig | undefined {
return connectionStore.getConfig(connectionId);
}
function connectionGroupLabel(connectionId: string): string {
return connectionGroupPaths.value.get(connectionId)?.join(" / ") || t("connectionGroup.ungroupedLabel");
}
function databaseOptionIsProduction(database: string): boolean {
if (!database || props.activeConnection?.is_production) return false;
return productionContextForDatabase(props.activeConnection, database).reason === "database";
@@ -10,6 +10,7 @@ import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
import DatabaseIcon from "@/components/icons/DatabaseIcon.vue";
import ConnectionGroupBadge from "@/components/connection/ConnectionGroupBadge.vue";
import { useToast } from "@/composables/useToast";
import { useConnectionStore } from "@/stores/connectionStore";
import { useProductionSafetyStore } from "@/stores/productionSafetyStore";
@@ -502,9 +503,10 @@ watch(
</SelectTrigger>
<SelectContent position="popper">
<SelectItem v-for="c in sqlConnections" :key="c.id" :value="c.id">
<div class="flex items-center gap-1.5">
<DatabaseIcon :db-type="c.driver_profile || c.db_type" class="w-3.5 h-3.5" />
{{ c.name }}
<div class="flex min-w-0 items-center gap-1.5">
<DatabaseIcon :db-type="c.driver_profile || c.db_type" class="w-3.5 h-3.5 shrink-0" />
<ConnectionGroupBadge :connection-id="c.id" />
<span class="min-w-0 flex-1 truncate">{{ c.name }}</span>
</div>
</SelectItem>
</SelectContent>
@@ -8,6 +8,7 @@ import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
import SearchableSelect from "@/components/ui/searchable-select/SearchableSelect.vue";
import ConnectionGroupBadge from "@/components/connection/ConnectionGroupBadge.vue";
import { useConnectionStore } from "@/stores/connectionStore";
import DatabaseIcon from "@/components/icons/DatabaseIcon.vue";
import * as api from "@/lib/backend/api";
@@ -382,6 +383,7 @@ function getConnectionName(id: string) {
<template #option-label="{ option, label }">
<div class="flex min-w-0 items-center gap-1.5">
<DatabaseIcon :db-type="sqlConnections.find((c) => c.id === option)?.db_type ?? 'mysql'" class="h-3.5 w-3.5 shrink-0" />
<ConnectionGroupBadge :connection-id="option" />
<span class="min-w-0 flex-1 truncate">{{ label }}</span>
</div>
</template>
@@ -445,6 +447,7 @@ function getConnectionName(id: string) {
<template #option-label="{ option, label }">
<div class="flex min-w-0 items-center gap-1.5">
<DatabaseIcon :db-type="sqlConnections.find((c) => c.id === option)?.db_type ?? 'mysql'" class="h-3.5 w-3.5 shrink-0" />
<ConnectionGroupBadge :connection-id="option" />
<span class="min-w-0 flex-1 truncate">{{ label }}</span>
</div>
</template>