From 8b6689c4452a5af78f715dcee8712fb1bcdb1aad Mon Sep 17 00:00:00 2001 From: Senior Frontend Engineer Date: Tue, 31 Mar 2026 10:14:13 +0000 Subject: [PATCH] feat(desktop): stabilize connection workspace state Absorb the local workspace drift for connection session handling, database switching, inspector readability helpers, and the bounded add-key preview flow. Co-Authored-By: Paperclip --- apps/desktop/src/App.tsx | 198 +++++----- apps/desktop/src/lib/add-key-draft.test.ts | 62 ++++ apps/desktop/src/lib/add-key-draft.ts | 67 ++++ .../src/lib/connection-session.test.ts | 151 ++++++++ apps/desktop/src/lib/connection-session.ts | 179 +++++++++ .../desktop/src/lib/database-switcher.test.ts | 74 ++++ apps/desktop/src/lib/database-switcher.ts | 29 ++ .../src/lib/inspector-readability.test.ts | 183 ++++++++++ apps/desktop/src/lib/inspector-readability.ts | 340 ++++++++++++++++++ 9 files changed, 1194 insertions(+), 89 deletions(-) create mode 100644 apps/desktop/src/lib/add-key-draft.test.ts create mode 100644 apps/desktop/src/lib/add-key-draft.ts create mode 100644 apps/desktop/src/lib/connection-session.test.ts create mode 100644 apps/desktop/src/lib/connection-session.ts create mode 100644 apps/desktop/src/lib/database-switcher.test.ts create mode 100644 apps/desktop/src/lib/database-switcher.ts create mode 100644 apps/desktop/src/lib/inspector-readability.test.ts create mode 100644 apps/desktop/src/lib/inspector-readability.ts diff --git a/apps/desktop/src/App.tsx b/apps/desktop/src/App.tsx index 4ee6544..a63b35c 100644 --- a/apps/desktop/src/App.tsx +++ b/apps/desktop/src/App.tsx @@ -3,6 +3,7 @@ import { startTransition, useDeferredValue, useEffect, + useRef, useState, type ChangeEvent, type FormEvent, @@ -82,6 +83,14 @@ import { updateDemoStringValue, } from "./lib/demo-workspace"; import { buildDatabaseSwitcherLabels } from "./lib/database-switcher"; +import { + applyConnectionTestFailure, + applyConnectionTestSuccess, + buildConnectionSessionSummary, + formatConnectionCardDetailLabel, + formatConnectionStatusLabel, + markConnectionTesting, +} from "./lib/connection-session"; import { createDemoKeyRecord, findDuplicateKeyName, @@ -493,7 +502,9 @@ function App() { const [addKeyDialogOpen, setAddKeyDialogOpen] = useState(false); const [deleteDialogOpen, setDeleteDialogOpen] = useState(false); const [pendingMutation, setPendingMutation] = useState(null); - const [isConnectionTestRunning, setIsConnectionTestRunning] = useState(false); + const [connectionTestState, setConnectionTestState] = useState<{ connectionId: string } | null>( + null, + ); const [isCommandRunning, setIsCommandRunning] = useState(false); const [isBrowseLoading, setIsBrowseLoading] = useState(false); const [isInspectorLoading, setIsInspectorLoading] = useState(false); @@ -528,6 +539,9 @@ function App() { const activeConnection = connections.find((connection) => connection.id === activeConnectionId) ?? connections[0]; + const activeConnectionIdRef = useRef(activeConnectionId); + const activeConnectionNameRef = useRef(activeConnection.name); + const activeDbRef = useRef(activeDb); const databaseOptions = buildDatabaseSwitcherLabels(parseDatabaseLabel(activeDb)); const searchState = resolveKeyBrowserSearchState(search); const deferredSearchState = resolveKeyBrowserSearchState(deferredSearch); @@ -591,6 +605,20 @@ function App() { ttlWriteSupported, }); const localSmokeFixtureActive = isLocalSmokeFixtureConnection(activeConnection); + const isConnectionTestRunning = connectionTestState !== null; + const activeConnectionTestRunning = connectionTestState?.connectionId === activeConnection.id; + const otherTestingConnectionName = + connectionTestState !== null && connectionTestState.connectionId !== activeConnection.id + ? connections.find((connection) => connection.id === connectionTestState.connectionId)?.name ?? + "another connection" + : null; + const connectionSessionSummary = buildConnectionSessionSummary({ + connection: activeConnection, + databaseLabel: activeDb, + tauriAvailable, + activeTestRunning: activeConnectionTestRunning, + otherTestingConnectionName, + }); const localSmokeFilterActive = search.trim() === localSmokeFixtureSearchText; const ttlDraftError = ttlDraft.trim() ? validateTtlDraft(ttlDraft) : null; const nextTtlMillis = @@ -660,6 +688,12 @@ function App() { bannerMessage: banner.message, }); + useEffect(() => { + activeConnectionIdRef.current = activeConnectionId; + activeConnectionNameRef.current = activeConnection.name; + activeDbRef.current = activeDb; + }, [activeConnectionId, activeConnection.name, activeDb]); + useEffect(() => { if (!tauriAvailable) { startTransition(() => { @@ -1538,23 +1572,14 @@ function App() { const handleTestConnection = async () => { const connection = activeConnection; - const request = toRedisConnectionRequest(connection, activeDb); + const databaseLabel = activeDb; + const request = toRedisConnectionRequest(connection, databaseLabel); startTransition(() => { - setIsConnectionTestRunning(true); - setConnections((current) => - current.map((item) => - item.id === connection.id - ? { - ...item, - status: "checking", - detail: "Live test in progress", - } - : item, - ), - ); + setConnectionTestState({ connectionId: connection.id }); + setConnections((current) => markConnectionTesting(current, connection.id)); showNeutralBanner( - `Testing ${connection.name} against ${activeDb} using the current desktop contract.`, + `Testing ${connection.name} against ${databaseLabel} using the current desktop contract.`, ); }); @@ -1574,7 +1599,7 @@ function App() { showNeutralBanner( `Tauri runtime is unavailable in browser dev mode, so connection testing stayed in demo fallback for ${connection.name}.`, ); - setIsConnectionTestRunning(false); + setConnectionTestState(null); }); return; } @@ -1586,46 +1611,46 @@ function App() { startTransition(() => { setConnections((current) => - current.map((item) => - item.id === connection.id - ? { - ...item, - status: "healthy", - detail: result.round_trip_status, - target: { - ...item.target, - database: result.selected_database, - username: result.authenticated_as ?? item.target.username, - }, - } - : item, - ), + applyConnectionTestSuccess(current, connection.id, { + roundTripStatus: result.round_trip_status, + selectedDatabase: result.selected_database, + authenticatedAs: result.authenticated_as, + }), ); - setActiveDb(formatDatabaseLabel(result.selected_database)); - showAccentBanner( - `Live Redis test passed for ${connection.name} on ${formatDatabaseLabel(result.selected_database)}. Round-trip status: ${result.round_trip_status}.`, + setConnectionTestState(null); + + if (activeConnectionIdRef.current === connection.id) { + setActiveDb(formatDatabaseLabel(result.selected_database)); + setSelectedKeyId(null); + showAccentBanner( + `Live Redis test passed for ${connection.name} on ${formatDatabaseLabel(result.selected_database)}. Round-trip status: ${result.round_trip_status}.`, + ); + return; + } + + showNeutralBanner( + `Live Redis test passed for ${connection.name}; current workspace stayed on ${activeConnectionNameRef.current} / ${activeDbRef.current}.`, ); - setIsConnectionTestRunning(false); }); } catch (error) { + const errorCode = formatBackendErrorCodeLabel(toBackendError(error).code); + startTransition(() => { - setConnections((current) => - current.map((item) => - item.id === connection.id - ? { - ...item, - status: "error", - detail: formatBackendErrorCodeLabel(toBackendError(error).code), - } - : item, - ), + setConnections((current) => applyConnectionTestFailure(current, connection.id, errorCode)); + setConnectionTestState(null); + + if (activeConnectionIdRef.current === connection.id) { + showBackendErrorBanner(error, { + operation: "connection_test", + connectionName: connection.name, + databaseLabel, + }); + return; + } + + showNeutralBanner( + `Live Redis test failed for ${connection.name}. The current workspace stayed on ${activeConnectionNameRef.current} / ${activeDbRef.current}; reopen ${connection.name} to retry after reviewing its card status.`, ); - showBackendErrorBanner(error, { - operation: "connection_test", - connectionName: connection.name, - databaseLabel: activeDb, - }); - setIsConnectionTestRunning(false); }); } }; @@ -1778,7 +1803,7 @@ function App() { } label="Status" - value={formatConnectionStatus(activeConnection)} + value={formatConnectionStatusLabel(activeConnection)} /> } @@ -1838,7 +1863,7 @@ function App() {

{connection.name}

{formatEndpoint(connection.target)}

- {formatConnectionCardDetail(connection)} + {formatConnectionCardDetailLabel(connection)}

{connection.environment} @@ -1958,9 +1983,32 @@ function App() { onClick={handleTestConnection} disabled={isConnectionTestRunning} > - {isConnectionTestRunning ? "Testing..." : tauriAvailable ? "Test live" : "Test demo"} + {activeConnectionTestRunning + ? "Testing..." + : isConnectionTestRunning + ? "Test running elsewhere" + : tauriAvailable + ? "Test live" + : "Test demo"} + +
+
+
+

Connection session

+

+ {connectionSessionSummary.summary} +

+
+ + {connectionSessionSummary.badgeLabel} + +
+

+ {connectionSessionSummary.hint} +

+
@@ -2106,6 +2154,7 @@ function App() { ? `${filteredKeys.length}${liveHasMore ? "+" : ""} visible in ${activeDb}` : `${filteredKeys.length} of ${demoKeys.length} keys in ${activeDb}`} + Preview