diff --git a/apps/desktop/src/components/mq/MqAdminConsole.vue b/apps/desktop/src/components/mq/MqAdminConsole.vue index 6b13410d0e..e19f9736ee 100644 --- a/apps/desktop/src/components/mq/MqAdminConsole.vue +++ b/apps/desktop/src/components/mq/MqAdminConsole.vue @@ -18,6 +18,7 @@ import { resolveInitialMqTab, resolveMqSystemKindFromConnection, resolveRabbitMqDefaultVhost, + resolveTopicSelectedTab, type MqTab, } from "@/lib/mq/mqConsoleDefaults"; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"; @@ -285,11 +286,7 @@ function handleNamespaceRolesSelected(namespace: string) { function handleTopicSelected(topic: TopicInfo) { selectedTopic.value = topic; selectedSubscriptionName.value = undefined; - if (isRocketMqCluster.value) { - activeTab.value = canManageSubscriptions.value ? "subscriptions" : "topics"; - } else { - activeTab.value = isFlatMqCluster.value ? "monitoring" : canManageSubscriptions.value ? "subscriptions" : "monitoring"; - } + activeTab.value = resolveTopicSelectedTab({ systemKind: mqSystemKind.value, capabilities: effectiveCapabilities.value }); } function handleNavigateTab(payload: { tab: MqTab; topic?: TopicInfo; subscription?: string; preferDlqTopic?: boolean }) { diff --git a/apps/desktop/src/lib/mq/__tests__/mqConsoleDefaults.spec.ts b/apps/desktop/src/lib/mq/__tests__/mqConsoleDefaults.spec.ts index 034ec7f73a..45992f5220 100644 --- a/apps/desktop/src/lib/mq/__tests__/mqConsoleDefaults.spec.ts +++ b/apps/desktop/src/lib/mq/__tests__/mqConsoleDefaults.spec.ts @@ -11,6 +11,7 @@ import { resolveMqSystemKindFromConnection, resolveRabbitMqDefaultVhost, resolveRabbitMqSendNamespace, + resolveTopicSelectedTab, } from "@/lib/mq/mqConsoleDefaults"; describe("mqConsoleDefaults", () => { @@ -192,4 +193,30 @@ describe("mqConsoleDefaults", () => { // Nothing to go on in all-vhosts mode: fall back to the connection default vhost. expect(resolveRabbitMqSendNamespace(undefined, "*", undefined)).toBeUndefined(); }); + + it("routes RabbitMQ queue selection to Messages, not the cluster-wide Monitoring tab (#5984)", () => { + // RabbitMqMonitoringPanel is cluster-wide and ignores the selected topic entirely, + // so landing there after clicking a queue drops all context about that queue. + expect(resolveTopicSelectedTab({ systemKind: "rabbitmq", capabilities: capabilities("rabbitmq") })).toBe("messages"); + }); + + it("falls back RabbitMQ queue selection to Topics when message sending is unsupported", () => { + expect(resolveTopicSelectedTab({ systemKind: "rabbitmq", capabilities: { ...capabilities("rabbitmq"), supportsSendMessage: false } })).toBe("topics"); + }); + + it("still routes Kafka/Pulsar topic selection to the per-topic Monitoring tab", () => { + // Unlike RabbitMQ, Kafka/Pulsar's MonitoringPanel is scoped to the selected topic, + // so routing there after selection is correct and must stay unchanged. + expect(resolveTopicSelectedTab({ systemKind: "kafka", capabilities: capabilities("kafka") })).toBe("monitoring"); + expect(resolveTopicSelectedTab({ systemKind: undefined, capabilities: capabilities(undefined) })).toBe("subscriptions"); + }); + + it("still routes RocketMQ topic selection to Subscriptions, falling back to Topics", () => { + expect(resolveTopicSelectedTab({ systemKind: "rocketmq", capabilities: capabilities("rocketmq") })).toBe("subscriptions"); + expect(resolveTopicSelectedTab({ systemKind: "rocketmq", capabilities: { ...capabilities("rocketmq"), supportsSubscriptions: false } })).toBe("topics"); + }); }); + +function capabilities(systemKind: Parameters[0]) { + return defaultMqCapabilitiesForSystemKind(systemKind); +} diff --git a/apps/desktop/src/lib/mq/mqConsoleDefaults.ts b/apps/desktop/src/lib/mq/mqConsoleDefaults.ts index 872340c093..80524deb86 100644 --- a/apps/desktop/src/lib/mq/mqConsoleDefaults.ts +++ b/apps/desktop/src/lib/mq/mqConsoleDefaults.ts @@ -204,3 +204,24 @@ export function resolveInitialMqTab(options: { initialTab?: MqTab; initialTenant if (options.initialTenant) return "namespaces"; return "tenants"; } + +/** + * Resolve which tab to switch to after the user selects a topic/queue row. + * + * RabbitMQ's "monitoring" tab (RabbitMqMonitoringPanel) is a cluster-wide + * overview with no per-topic scoping, unlike Kafka/Pulsar's monitoring tab + * (MonitoringPanel), which does take the selected topic and shows its stats. + * Routing RabbitMQ topic selection to "monitoring" therefore drops all + * context about the queue just clicked (see #5984). "messages" shows a + * message browser scoped to the selected queue instead. + */ +export function resolveTopicSelectedTab(options: { systemKind?: MqSystemKind; capabilities: MqCapabilities }): MqTab { + const { systemKind, capabilities } = options; + if (systemKind === "rocketmq") { + return capabilities.supportsSubscriptions ? "subscriptions" : "topics"; + } + if (systemKind === "rabbitmq") { + return capabilities.supportsSendMessage ? "messages" : "topics"; + } + return isFlatMqSystemKind(systemKind) ? "monitoring" : capabilities.supportsSubscriptions ? "subscriptions" : "monitoring"; +}