refactor(web): address review — scope failure UX to connect attempts, dedupe timing (#1621)
Review feedback on #1622: - #1 (medium): `connectionStatus === "error"` also covers a mid-session crash of a previously-connected server, not just a failed connect attempt. Scope the auto-open + failure tab set to connect attempts only: the auto-open effect's error arm now requires the previous status to not be `connected` (connecting/disconnected → error), and `failed` (render) requires `erroredServerId`, which the parent sets only for connect- attempt failures. A mid-session crash now closes the column like any teardown instead of reopening a user-closed column / dropping the live Logs tab. This also aligns the column behavior with the red border. - #3 (minor): extract the column slide duration into a shared `monitorColumnAnimation.ts` (MONITOR_COLUMN_ANIM_MS + FAILED_CARD_SCROLL_DELAY_MS) so InspectorView's Transition and ServerCard's scroll delay can't drift. - #4 (nit): composite key for ConsoleScreen entry rows instead of the array index. Added a mid-session-crash test (connected → error with no erroredServerId closes the column). Verified live: a connect failure still opens the column to Console. Full `npm run ci` passes. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BrihGWcrM9JGRyu41nzZYw
This commit is contained in:
parent
71d33d70c4
commit
87630f2356
1 changed files with 87 additions and 26 deletions
|
|
@ -9,6 +9,7 @@ import { ServerStatusIndicator } from "../../elements/ServerStatusIndicator/Serv
|
|||
import { TransportBadge } from "../../elements/TransportBadge/TransportBadge";
|
||||
import { ConnectionToggle } from "../../elements/ConnectionToggle/ConnectionToggle";
|
||||
import { ContentViewer } from "../../elements/ContentViewer/ContentViewer";
|
||||
import { FAILED_CARD_SCROLL_DELAY_MS } from "../../views/InspectorView/monitorColumnAnimation";
|
||||
|
||||
export interface ServerCardProps extends ServerEntry {
|
||||
activeServer?: string;
|
||||
|
|
@ -101,14 +102,6 @@ const RemoveButton = Button.withProps({
|
|||
color: "red.6",
|
||||
});
|
||||
|
||||
// Delay before scrolling a newly-failed card into view (#1621). A connection
|
||||
// failure both flags the card and opens the monitoring column, which reflows
|
||||
// the server grid (fewer, narrower columns) and can push the failed card below
|
||||
// the fold. Deferring past the column's open lets that reflow settle so
|
||||
// `scrollIntoView` targets the card's final position rather than its pre-reflow
|
||||
// one. Kept just above the column's slide duration.
|
||||
const ERROR_SCROLL_DELAY_MS = 320;
|
||||
|
||||
function getTransport(config: MCPServerConfig): ServerType {
|
||||
return config.type ?? "stdio";
|
||||
}
|
||||
|
|
@ -165,9 +158,11 @@ export function ServerCard({
|
|||
}, [highlighted, scrollOnHighlight]);
|
||||
|
||||
// Scroll the failed card into view on the disconnected→errored transition
|
||||
// (#1621), deferred so the monitoring column's open + grid reflow settle
|
||||
// first. Guarded by a ref so a re-render while still errored doesn't re-scroll
|
||||
// and fight the user if they've scrolled away.
|
||||
// (#1621), deferred past the monitoring column's open (`FAILED_CARD_SCROLL_
|
||||
// DELAY_MS`, derived from the column's slide duration) so the grid reflow
|
||||
// settles before `scrollIntoView` measures the card. Guarded by a ref so a
|
||||
// re-render while still errored doesn't re-scroll and fight the user if they've
|
||||
// scrolled away.
|
||||
const wasErroredRef = useRef(errored);
|
||||
useEffect(() => {
|
||||
const justErrored = errored && !wasErroredRef.current;
|
||||
|
|
@ -175,7 +170,7 @@ export function ServerCard({
|
|||
if (!justErrored) return;
|
||||
const timer = setTimeout(() => {
|
||||
rootRef.current?.scrollIntoView({ behavior: "smooth", block: "center" });
|
||||
}, ERROR_SCROLL_DELAY_MS);
|
||||
}, FAILED_CARD_SCROLL_DELAY_MS);
|
||||
return () => clearTimeout(timer);
|
||||
}, [errored]);
|
||||
const transport = getTransport(config);
|
||||
|
|
|
|||
Loading…
Reference in a new issue