feat(connections): redesign connection list and detail UI#2697
feat(connections): redesign connection list and detail UI#2697
Conversation
- Modal-first flow: clicking any connection card opens a modal showing instances + available tools (ConnectionInstancesModal), instead of navigating directly to detail - "Connect" on catalog items goes directly to the connect/OAuth flow - Add tabs (Connected / All / Built by me / Needs config) to filter connections - Connection detail redesigned as a dashboard: header, activity chart, capabilities list, conditional agents panel, info card, settings sheet - Agents panel hidden when no agents are using the connection - Remove Active badge and tools count from connection detail header - Add equal card heights (h-full) to ConnectionCard grid - Add xl size to IntegrationIcon for detail header - New components: ConnectionActivity, ConnectionAgentsPanel, ConnectionCapabilities, ConnectionDetailHeader, ConnectionInfoCard - New utility: groupConnections (groups connections by app_name) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Import CollectionTabs and ConnectionInstancesModal in connections page - Remove Store from Build group in sidebar - Remove Browse Store button from connections CTA Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Display friendly names instead of slugs in catalog cards (All tab) - Prefer metadata friendly_name and server.title over server.name - Increase icon size from 32px to 36px in connection cards for better visibility
🧪 BenchmarkShould we run the Virtual MCP strategy benchmark for this PR? React with 👍 to run the benchmark.
Benchmark will run on the next push after you react. |
Release OptionsShould a new version be published when this PR is merged? React with an emoji to vote on the release type:
Current version: Deployment
|
There was a problem hiding this comment.
5 issues found across 20 files
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="apps/mesh/src/web/routes/orgs/connections.tsx">
<violation number="1" location="apps/mesh/src/web/routes/orgs/connections.tsx:2149">
P1: On the "All" tab, users with no existing connections will see the empty state instead of browsable catalog items. The empty-state guard should also account for `catalogItems` so the registry grid still renders when there are items to browse.</violation>
</file>
<file name="apps/mesh/src/web/components/details/connection/connection-agents-panel.tsx">
<violation number="1" location="apps/mesh/src/web/components/details/connection/connection-agents-panel.tsx:17">
P2: This early return hides the section's built-in empty state, so connections without agents lose the "Create an agent" CTA on the detail page.</violation>
</file>
<file name="apps/mesh/src/web/components/details/connection/connection-capabilities.tsx">
<violation number="1" location="apps/mesh/src/web/components/details/connection/connection-capabilities.tsx:48">
P2: The collection parser is too narrow for repository-supported `COLLECTION_*` tools. Suffixes like `_FILTERS`, `_SEARCH`, `_VERSIONS`, and `_GET_STEP_RESULT` will be mislabeled instead of grouped under their collection.</violation>
</file>
<file name="apps/mesh/src/web/components/details/connection/connection-activity.tsx">
<violation number="1" location="apps/mesh/src/web/components/details/connection/connection-activity.tsx:58">
P2: Include `orgId` in the activity query key so cached results cannot bleed across organization changes.</violation>
</file>
<file name="apps/mesh/src/web/components/details/connection/index.tsx">
<violation number="1" location="apps/mesh/src/web/components/details/connection/index.tsx:519">
P1: Don't gate `SettingsTab` on `hasMcpBinding` here. It already checks `isMCPAuthenticated` before the no-binding branch, so this wrapper suppresses the auth-required/all-set states for connections without an MCP binding.
(Based on your team's feedback about checking MCP authentication state before hasMcpBinding.) [FEEDBACK_USED]</violation>
</file>
Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.
| <Page.Content> | ||
| <div className="flex-1 overflow-auto p-5"> | ||
| {nonVirtualConnections.length === 0 ? ( | ||
| {tabFilteredConnections.length === 0 ? ( |
There was a problem hiding this comment.
P1: On the "All" tab, users with no existing connections will see the empty state instead of browsable catalog items. The empty-state guard should also account for catalogItems so the registry grid still renders when there are items to browse.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At apps/mesh/src/web/routes/orgs/connections.tsx, line 2149:
<comment>On the "All" tab, users with no existing connections will see the empty state instead of browsable catalog items. The empty-state guard should also account for `catalogItems` so the registry grid still renders when there are items to browse.</comment>
<file context>
@@ -2188,376 +1806,347 @@ function OrgMcpsContent() {
+ <Page.Content>
<div className="flex-1 overflow-auto p-5">
- {nonVirtualConnections.length === 0 ? (
+ {tabFilteredConnections.length === 0 ? (
<EmptyState
image={
</file context>
| {tabFilteredConnections.length === 0 ? ( | |
| {groupedForDisplay.length === 0 && catalogItems.length === 0 ? ( |
| onReauthenticate={handleAuthenticate} | ||
| onRemoveOAuth={handleRemoveOAuth} | ||
| /> | ||
| {hasMcpBinding && ( |
There was a problem hiding this comment.
P1: Don't gate SettingsTab on hasMcpBinding here. It already checks isMCPAuthenticated before the no-binding branch, so this wrapper suppresses the auth-required/all-set states for connections without an MCP binding.
(Based on your team's feedback about checking MCP authentication state before hasMcpBinding.)
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At apps/mesh/src/web/components/details/connection/index.tsx, line 519:
<comment>Don't gate `SettingsTab` on `hasMcpBinding` here. It already checks `isMCPAuthenticated` before the no-binding branch, so this wrapper suppresses the auth-required/all-set states for connections without an MCP binding.
(Based on your team's feedback about checking MCP authentication state before hasMcpBinding.) </comment>
<file context>
@@ -521,110 +466,119 @@ function ConnectionInspectorViewWithConnection({
+ onReauthenticate={handleAuthenticate}
+ onRemoveOAuth={handleRemoveOAuth}
+ />
+ {hasMcpBinding && (
+ <SettingsTab
+ connection={connection}
</file context>
| filters: [{ column: "connection_id", value: connection.id }], | ||
| }); | ||
|
|
||
| if (virtualMcps.length === 0) return null; |
There was a problem hiding this comment.
P2: This early return hides the section's built-in empty state, so connections without agents lose the "Create an agent" CTA on the detail page.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At apps/mesh/src/web/components/details/connection/connection-agents-panel.tsx, line 17:
<comment>This early return hides the section's built-in empty state, so connections without agents lose the "Create an agent" CTA on the detail page.</comment>
<file context>
@@ -0,0 +1,37 @@
+ filters: [{ column: "connection_id", value: connection.id }],
+ });
+
+ if (virtualMcps.length === 0) return null;
+
+ return (
</file context>
| */ | ||
| function collectionNameFromTool(toolName: string): string { | ||
| const match = toolName.match( | ||
| /^COLLECTION_([^_]+(?:_[^_]+)*?)_(LIST|GET|CREATE|UPDATE|DELETE)$/i, |
There was a problem hiding this comment.
P2: The collection parser is too narrow for repository-supported COLLECTION_* tools. Suffixes like _FILTERS, _SEARCH, _VERSIONS, and _GET_STEP_RESULT will be mislabeled instead of grouped under their collection.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At apps/mesh/src/web/components/details/connection/connection-capabilities.tsx, line 48:
<comment>The collection parser is too narrow for repository-supported `COLLECTION_*` tools. Suffixes like `_FILTERS`, `_SEARCH`, `_VERSIONS`, and `_GET_STEP_RESULT` will be mislabeled instead of grouped under their collection.</comment>
<file context>
@@ -0,0 +1,270 @@
+ */
+function collectionNameFromTool(toolName: string): string {
+ const match = toolName.match(
+ /^COLLECTION_([^_]+(?:_[^_]+)*?)_(LIST|GET|CREATE|UPDATE|DELETE)$/i,
+ );
+ if (match) {
</file context>
| const dateRange = getDateRange(timeframe); | ||
|
|
||
| const { data } = useSuspenseQuery({ | ||
| queryKey: KEYS.connectionActivity(connectionId, timeframe), |
There was a problem hiding this comment.
P2: Include orgId in the activity query key so cached results cannot bleed across organization changes.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At apps/mesh/src/web/components/details/connection/connection-activity.tsx, line 58:
<comment>Include `orgId` in the activity query key so cached results cannot bleed across organization changes.</comment>
<file context>
@@ -0,0 +1,225 @@
+ const dateRange = getDateRange(timeframe);
+
+ const { data } = useSuspenseQuery({
+ queryKey: KEYS.connectionActivity(connectionId, timeframe),
+ queryFn: async () => {
+ const result = (await client.callTool({
</file context>
What is this contribution about?
Redesigns the connections page and detail view with an improved card-based catalog layout, grouped instances, bulk actions, and a more polished detail panel. Also fixes catalog cards showing slug names instead of friendly names, and increases integration icon size to 36px for better visual clarity.
Screenshots/Demonstration
How to Test
Migration Notes
No database migrations required.
Review Checklist
Summary by cubic
Redesigns the Connections list and detail views with a modal-first flow, grouped instances, and a dashboard-style detail page. Fixes catalog cards to show friendly names and enlarges integration icons for clearer scanning.
New Features
ConnectionInstancesModalwith instances and tools; Connect goes straight to OAuth.app_nameviagroupConnections.IntegrationIconxlsize added for the detail header.KEYS.connectionActivityand monitoring bucket/stat helpers for charts.Bug Fixes
Written for commit 545a6e7. Summary will update on new commits.