From a216aa9060acac346a34ef9ea451bc38f5945d68 Mon Sep 17 00:00:00 2001 From: Viktor Avelino <64113566+viktoravelino@users.noreply.github.com> Date: Mon, 13 Apr 2026 15:10:07 -0400 Subject: [PATCH] fix(ui): refactor connection panel and fix search empty state (#12659) * fix(ui): refactor connection panel and fix search empty state rendering Extract connection state management into useConnectionPanelState hook and search/list UI into ConnectionSearchList component. Fixes bug where blank list items rendered before the empty state when search returned no results. * fix(ui): prevent modal jump when clicking connection items in Chrome Chrome scrolls the nearest scrollable ancestor when focusing sr-only inputs inside labels. Adding relative + overflow-hidden to the label contains the scroll-into-view behavior within the label bounds. --- .../deployments/use-get-deployment-configs.ts | 1 + .../components/connection-search-list.tsx | 95 +++++++ .../components/radio-select-item.tsx | 4 +- .../step-attach-flows-connection-panel.tsx | 87 +----- .../components/step-attach-flows.tsx | 252 +++++------------- .../hooks/use-connection-panel-state.ts | 223 ++++++++++++++++ .../MainPage/pages/deploymentsPage/types.ts | 2 + 7 files changed, 399 insertions(+), 265 deletions(-) create mode 100644 src/frontend/src/pages/MainPage/pages/deploymentsPage/components/connection-search-list.tsx create mode 100644 src/frontend/src/pages/MainPage/pages/deploymentsPage/hooks/use-connection-panel-state.ts diff --git a/src/frontend/src/controllers/API/queries/deployments/use-get-deployment-configs.ts b/src/frontend/src/controllers/API/queries/deployments/use-get-deployment-configs.ts index 3d98c29192..f02b34ef20 100644 --- a/src/frontend/src/controllers/API/queries/deployments/use-get-deployment-configs.ts +++ b/src/frontend/src/controllers/API/queries/deployments/use-get-deployment-configs.ts @@ -7,6 +7,7 @@ export interface DeploymentConfigItem { connection_id: string; app_id: string; type?: string; + environment?: string; } export interface DeploymentConfigListResponse { diff --git a/src/frontend/src/pages/MainPage/pages/deploymentsPage/components/connection-search-list.tsx b/src/frontend/src/pages/MainPage/pages/deploymentsPage/components/connection-search-list.tsx new file mode 100644 index 0000000000..6e0130dbf4 --- /dev/null +++ b/src/frontend/src/pages/MainPage/pages/deploymentsPage/components/connection-search-list.tsx @@ -0,0 +1,95 @@ +import { memo, useMemo, useState } from "react"; +import ForwardedIconComponent from "@/components/common/genericIconComponent"; +import { Input } from "@/components/ui/input"; +import type { ConnectionItem } from "../types"; +import { CheckboxSelectItem } from "./radio-select-item"; + +interface ConnectionSearchListProps { + connections: ConnectionItem[]; + selectedConnections: Set; + onToggleConnection: (id: string) => void; + onSwitchToCreate: () => void; +} + +export const ConnectionSearchList = memo(function ConnectionSearchList({ + connections, + selectedConnections, + onToggleConnection, + onSwitchToCreate, +}: ConnectionSearchListProps) { + const [searchQuery, setSearchQuery] = useState(""); + + const filteredConnections = useMemo(() => { + const sorted = [...connections].sort((a, b) => { + if (a.isNew && !b.isNew) return -1; + if (!a.isNew && b.isNew) return 1; + return 0; + }); + if (!searchQuery.trim()) return sorted; + const q = searchQuery.toLowerCase(); + return sorted.filter( + (c) => c.name.toLowerCase().includes(q) || c.id.toLowerCase().includes(q), + ); + }, [connections, searchQuery]); + + if (connections.length === 0) { + return ( +
+ +
+

+ No connections yet +

+

+ Create a connection to attach credentials to this flow. +

+
+ +
+ ); + } + + return ( + <> +
+ setSearchQuery(e.target.value)} + /> +
+ {filteredConnections.length === 0 ? ( +

+ No connections match “{searchQuery}” +

+ ) : ( + filteredConnections.map((conn) => ( + onToggleConnection(conn.id)} + data-testid={`connection-item-${conn.id}`} + > +
+ + {conn.name} + +
+
+ )) + )} + + ); +}); diff --git a/src/frontend/src/pages/MainPage/pages/deploymentsPage/components/radio-select-item.tsx b/src/frontend/src/pages/MainPage/pages/deploymentsPage/components/radio-select-item.tsx index 4d2565ebc0..ccf6dee143 100644 --- a/src/frontend/src/pages/MainPage/pages/deploymentsPage/components/radio-select-item.tsx +++ b/src/frontend/src/pages/MainPage/pages/deploymentsPage/components/radio-select-item.tsx @@ -31,7 +31,7 @@ export function CheckboxSelectItem({