diff --git a/apps/desktop/src/components/connection/ConnectionDialog.vue b/apps/desktop/src/components/connection/ConnectionDialog.vue index 1ff7ba37a3..42a43547d3 100644 --- a/apps/desktop/src/components/connection/ConnectionDialog.vue +++ b/apps/desktop/src/components/connection/ConnectionDialog.vue @@ -69,8 +69,8 @@ import { normalizeRabbitmqAddresses } from "@/lib/connection/rabbitmqAddresses"; import { detectMqUiAuthKind, isMqAuthKindAllowedForSystem, type MqUiAuthKind } from "@/lib/connection/mqAuth"; import { driverInstallProgressChannel, driverInstallProgressPercent, isDriverInstallProgressForOperation, type DriverInstallProgress } from "@/lib/connection/driverInstallProgressUi"; import { requiresSqlServerLegacyCompatibilityComponent, setSqlServerLegacyCompatibilityConfig, sqlServerUsesLegacyCompatibility, SQLSERVER_LEGACY_COMPATIBILITY_DRIVER_KEY } from "@/lib/connection/sqlServerLegacyCompatibility"; -import { normalizeNacosEndpoint, normalizeNacosMetricsUrl } from "@/lib/nacos/nacosAdmin"; -import { nacosNamespaceIdentity, normalizeNacosNamespaceSelection, normalizeNacosNamespacesForDisplay } from "@/lib/nacos/nacosNamespaceVisibility"; +import { normalizeNacosEndpoint, normalizeNacosMetricsUrl, parseNacosManagedNamespaces } from "@/lib/nacos/nacosAdmin"; +import { loadReadableNacosNamespaces, nacosNamespaceIdentity, normalizeNacosNamespaceSelection } from "@/lib/nacos/nacosNamespaceVisibility"; import { ArrowLeft, ArrowDown, @@ -821,11 +821,12 @@ const mqKafkaSaslMechanismOptions = [ { value: "SCRAM-SHA-512", label: "SCRAM-SHA-512" }, ]; const nacosImplementation = ref("nacos"); -// Nacos 2 and 3 expose different API planes (and Nacos 3 commonly needs a -// separate Console address). New connections must therefore choose an -// explicit version instead of relying on endpoint-shape guessing. +// Nacos 2 and 3 expose different API planes. New connections must therefore +// choose an explicit version instead of relying on endpoint-shape guessing. const nacosVersionMode = ref("v2"); const nacosServerAddr = ref(""); +const nacosOrdinaryAccount = ref(false); +const nacosManagedNamespacesText = ref(""); const nacosRNacosConsoleAddr = ref(""); const nacosHistoryEnabled = ref(false); const nacosConsoleAuthKind = ref("inherit"); @@ -1390,6 +1391,8 @@ function resetNacosFields(config?: Partial) { const serverAddr = config?.serverAddr?.trim() || ""; const contextPath = config?.contextPath?.trim() || ""; nacosServerAddr.value = serverAddr && contextPath && contextPath !== "/" && !serverAddr.endsWith(contextPath) ? `${serverAddr.replace(/\/+$/, "")}/${contextPath.replace(/^\/+/, "")}` : serverAddr; + nacosOrdinaryAccount.value = !!config?.managedNamespaces?.length; + nacosManagedNamespacesText.value = (config?.managedNamespaces || []).join("\n"); nacosRNacosConsoleAddr.value = config?.rnacosConsoleAddr?.trim() || ""; nacosHistoryEnabled.value = config?.rnacosHistoryEnabled ?? !!config?.rnacosConsoleAddr; const consoleAuth = config?.rnacosConsoleAuth || { kind: "inherit" }; @@ -1731,12 +1734,16 @@ function buildNacosAdminConfig(): NacosAdminConfig { if (nacosImplementation.value === "rnacos" && normalized.warnings.length) { throw new Error(t("connection.nacosRNacosOpenApiRequired")); } - const rnacosExtensionsEnabled = nacosImplementation.value === "rnacos" && nacosHistoryEnabled.value; - const rnacosConsoleConfigured = rnacosExtensionsEnabled && !!nacosRNacosConsoleAddr.value.trim(); - if (rnacosExtensionsEnabled && !rnacosConsoleConfigured) { + const rnacosConsoleConfigured = nacosImplementation.value === "rnacos" && !!nacosRNacosConsoleAddr.value.trim(); + if (nacosImplementation.value === "rnacos" && nacosHistoryEnabled.value && !rnacosConsoleConfigured) { throw new Error(t("connection.nacosRNacosConsoleUrlRequired")); } let rnacosConsoleAuth: NacosRNacosConsoleAuth | undefined; + const usesManagedNamespaces = nacosImplementation.value === "nacos" && nacosAuthKind.value === "usernamePassword" && nacosOrdinaryAccount.value; + const managedNamespaces = usesManagedNamespaces ? parseNacosManagedNamespaces(nacosManagedNamespacesText.value) : []; + if (usesManagedNamespaces && managedNamespaces.length === 0) { + throw new Error(t("nacos.nacosOrdinaryNamespacesRequired")); + } let metricsUrl: string | undefined; if (nacosMetricsMode.value === "custom") { try { @@ -1762,7 +1769,8 @@ function buildNacosAdminConfig(): NacosAdminConfig { versionMode: nacosImplementation.value === "nacos" ? nacosVersionMode.value : undefined, serverAddr: normalized.serverAddr, contextPath: normalized.contextPath || undefined, - rnacosConsoleAddr: rnacosExtensionsEnabled ? nacosRNacosConsoleAddr.value.trim() || undefined : undefined, + managedNamespaces: managedNamespaces.length ? managedNamespaces : undefined, + rnacosConsoleAddr: rnacosConsoleConfigured ? nacosRNacosConsoleAddr.value.trim() : undefined, rnacosHistoryEnabled: nacosImplementation.value === "rnacos" ? nacosHistoryEnabled.value : undefined, rnacosConsoleAuth, auth: buildNacosAuth(), @@ -4426,7 +4434,7 @@ async function openVisibleNacosNamespacesPicker() { one_time: true, }; await api.connectDb(draftConfig); - const namespaces = normalizeNacosNamespacesForDisplay(await api.nacosListNamespaces(draftId)); + const namespaces = await loadReadableNacosNamespaces(draftId, api); visibleNacosNamespaces.value = [...namespaces].sort((left, right) => nacosNamespaceLabel(left).localeCompare(nacosNamespaceLabel(right))); const configured = form.value.visible_databases; const initialSelection = Array.isArray(configured) ? normalizeVisibleNacosNamespaceSelection(configured, visibleNacosNamespaces.value) : visibleNacosNamespaces.value.map(nacosNamespaceValue); @@ -4510,7 +4518,7 @@ function initialProductionDatabaseSelection(databaseNames: string[]): string[] { async function loadProductionDatabaseNames(connectionId: string, config: ConnectionConfig): Promise { if (config.db_type === "nacos") { - return normalizeNacosNamespacesForDisplay(await api.nacosListNamespaces(connectionId)).map((namespace) => namespace.namespace); + return (await loadReadableNacosNamespaces(connectionId, api)).map((namespace) => namespace.namespace); } if (config.db_type === "redis") { return (await api.redisListDatabases(connectionId)).map((database) => String(database.db)); @@ -6316,6 +6324,29 @@ function openExternalUrl(url: string) { +
+
+ + {{ t("nacos.nacosOrdinaryAccount") }} + {{ t("nacos.nacosOrdinaryAccountHint") }} + + +
+
+
+ + {{ t("nacos.nacosManagedNamespacesSeparator") }} +
+