You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The Server Info action on ServerCard is currently a no-op — App.tsx wires onServerInfo={todoNoop} (App.tsx:908). The presentational ServerInfoContent component already exists (clients/web/src/components/groups/ServerInfoContent/) and accepts the right props (initializeResult, clientCapabilities, transport, oauth?), but there is no modal that hosts it and no wiring from the click handler to a real popup.
This issue is to implement a ServerInfoModal that hosts the existing ServerInfoContent, gate the Server Info entry point on ServerCard so it only appears when the server is connected, and wire the modal to the InitializeResult produced by the active InspectorClient's connection handshake.
Current state
ServerInfoContent (clients/web/src/components/groups/ServerInfoContent/ServerInfoContent.tsx) — presentational, fully built, has its own test and story files.
ServerCard.tsx:161-168 — always renders the Server Info button regardless of connection status.
App.tsx:328-336 — already computes an InitializeResult from the connected InspectorClient (protocolVersion, capabilities, serverInfo, optional instructions). This is the data source the modal needs.
App.tsx:908 — onServerInfo={todoNoop}, so clicking the button does nothing.
Modal pattern to mirror: ServerSettingsModal (clients/web/src/components/groups/ServerSettingsModal/) — same shape (Mantine Modal wrapping a presentational content component, opened by a target-id state in App.tsx).
Proposed change
1. Create ServerInfoModal
clients/web/src/components/groups/ServerInfoModal/ServerInfoModal.tsx — a Mantine Modal wrapper around ServerInfoContent. Props:
The modal owns the framing (title, close button, sizing) and forwards everything else straight to ServerInfoContent. Mirror the structure of ServerSettingsModal for consistency.
2. Gate the Server Info button on ServerCard
In ServerCard.tsx:161-168, only render the Server Info SubtleButton when connection.status === \"connected\". The Settings button stays unconditional. The popup is only meaningful after a successful handshake — capabilities, instructions, and protocolVersion are all handshake-derived.
3. Wire the modal in App.tsx
Add a serverInfoModalOpen (or serverInfoTargetId) piece of state, parallel to settingsModalTargetId.
Replace onServerInfo={todoNoop} (App.tsx:908) with a handler that opens the modal for the active server. Since Server Info is gated on connection.status === \"connected\" (acceptance criterion above), the active server is the only valid target — no need to thread an id through.
Pass the already-computed initializeResult (App.tsx:328-336) into the modal. If initializeResult is undefined at render time (race between disconnect and modal close), the modal should close itself or render nothing rather than crash.
Source clientCapabilities and transport from the same place the connected ViewHeader already reads them (initializeResult is built right next to those). OAuth details are optional and can be threaded later if not readily available — leave a TODO if so.
Acceptance criteria
ServerInfoModal exists at clients/web/src/components/groups/ServerInfoModal/ with .tsx, .test.tsx, and .stories.tsx files mirroring the ServerSettingsModal layout.
Server Info button on ServerCard renders only when connection.status === \"connected\"; Settings button continues to render in all states.
Clicking Server Info on a connected card opens the modal, which displays the data from the active connection's InitializeResult (serverInfo, capabilities, protocolVersion, instructions).
Closing the modal (X button, ESC, click outside) returns to the Servers screen with no stale state.
ServerCard.test.tsx covers both branches (connected → Server Info present; disconnected/connecting/error → Server Info absent).
ServerInfoModal.test.tsx covers: open with a sample InitializeResult renders ServerInfoContent, close handler fires on the standard close paths.
ServerCard and ServerInfoModal stories cover the connected/non-connected variants and the modal-open state, so npm run test:storybook exercises the rendered UI.
Per-file coverage gate (lines ≥ 90, statements ≥ 85, functions ≥ 80, branches ≥ 50) passes for the new files.
Summary
The Server Info action on
ServerCardis currently a no-op —App.tsxwiresonServerInfo={todoNoop}(App.tsx:908). The presentationalServerInfoContentcomponent already exists (clients/web/src/components/groups/ServerInfoContent/) and accepts the right props (initializeResult,clientCapabilities,transport,oauth?), but there is no modal that hosts it and no wiring from the click handler to a real popup.This issue is to implement a
ServerInfoModalthat hosts the existingServerInfoContent, gate the Server Info entry point onServerCardso it only appears when the server is connected, and wire the modal to theInitializeResultproduced by the activeInspectorClient's connection handshake.Current state
ServerInfoContent(clients/web/src/components/groups/ServerInfoContent/ServerInfoContent.tsx) — presentational, fully built, has its own test and story files.ServerCard.tsx:161-168— always renders the Server Info button regardless of connection status.App.tsx:328-336— already computes anInitializeResultfrom the connectedInspectorClient(protocolVersion,capabilities,serverInfo, optionalinstructions). This is the data source the modal needs.App.tsx:908—onServerInfo={todoNoop}, so clicking the button does nothing.ServerSettingsModal(clients/web/src/components/groups/ServerSettingsModal/) — same shape (MantineModalwrapping a presentational content component, opened by a target-id state inApp.tsx).Proposed change
1. Create
ServerInfoModalclients/web/src/components/groups/ServerInfoModal/ServerInfoModal.tsx— a MantineModalwrapper aroundServerInfoContent. Props:The modal owns the framing (title, close button, sizing) and forwards everything else straight to
ServerInfoContent. Mirror the structure ofServerSettingsModalfor consistency.2. Gate the Server Info button on
ServerCardIn
ServerCard.tsx:161-168, only render the Server InfoSubtleButtonwhenconnection.status === \"connected\". The Settings button stays unconditional. The popup is only meaningful after a successful handshake — capabilities, instructions, and protocolVersion are all handshake-derived.3. Wire the modal in
App.tsxserverInfoModalOpen(orserverInfoTargetId) piece of state, parallel tosettingsModalTargetId.onServerInfo={todoNoop}(App.tsx:908) with a handler that opens the modal for the active server. Since Server Info is gated onconnection.status === \"connected\"(acceptance criterion above), the active server is the only valid target — no need to thread an id through.initializeResult(App.tsx:328-336) into the modal. IfinitializeResultisundefinedat render time (race between disconnect and modal close), the modal should close itself or render nothing rather than crash.clientCapabilitiesandtransportfrom the same place the connectedViewHeaderalready reads them (initializeResultis built right next to those). OAuth details are optional and can be threaded later if not readily available — leave a TODO if so.Acceptance criteria
ServerInfoModalexists atclients/web/src/components/groups/ServerInfoModal/with.tsx,.test.tsx, and.stories.tsxfiles mirroring theServerSettingsModallayout.ServerCardrenders only whenconnection.status === \"connected\"; Settings button continues to render in all states.InitializeResult(serverInfo, capabilities, protocolVersion, instructions).ServerCard.test.tsxcovers both branches (connected → Server Info present; disconnected/connecting/error → Server Info absent).ServerInfoModal.test.tsxcovers: open with a sampleInitializeResultrendersServerInfoContent, close handler fires on the standard close paths.ServerCardandServerInfoModalstories cover the connected/non-connected variants and the modal-open state, sonpm run test:storybookexercises the rendered UI.