import { useState } from "react"; import { Button, Group, Modal, Stack, Text } from "@mantine/core"; import { JsonEditor } from "../../elements/JsonEditor/JsonEditor"; import { isJsonObject } from "../../../utils/jsonObjectDraft"; export interface EditReplayModalProps { opened: boolean; /** The method being replayed, shown so the editor is unambiguous. */ method: string; /** The originating entry's params, seeded into the editor. */ params?: Record; /** * Re-issue the request with these params. `null` means "send no params", * which is a request an empty editor can legitimately express — see * {@link ReplayParamsOverride} for why it is not `undefined`. */ onSend: (params: Record | null) => void; onClose: () => void; } const MethodText = Text.withProps({ size: "sm", c: "dimmed", ff: "monospace", }); const Footer = Group.withProps({ justify: "flex-end", gap: "sm" }); /** * What the editor's text currently means: the params to send, or why they * cannot be sent. * * Empty text is "no params" rather than an error — a `tools/list` replay * genuinely carries none, and an empty editor wearing a red error would read as * broken. A non-object is reported separately from text that is not JSON at * all: JSON-RPC `params` must be a structured value, so `42` is a shape that * cannot be sent however finished it is. */ function parseParamsDraft( text: string, ): | { ok: true; value: Record | null } | { ok: false; error: string } { if (text.trim() === "") return { ok: true, value: null }; let parsed: unknown; try { parsed = JSON.parse(text); } catch { return { ok: false, error: "Not valid JSON — this cannot be sent" }; } if (!isJsonObject(parsed)) { return { ok: false, error: "Params must be a JSON object (`{ … }`)" }; } return { ok: true, value: parsed }; } /** * The modal's body, split out so its draft is owned by a component Mantine * unmounts on close — which is what makes reopening start from the entry's * params again rather than from whatever was last typed and abandoned. */ function EditReplayForm({ method, params, onSend, onClose, }: Omit) { const [draft, setDraft] = useState(() => params === undefined ? "" : JSON.stringify(params, null, 2), ); const parsed = parseParamsDraft(draft); return ( {method}
); } /** * Edit a Protocol entry's request params, then replay it (#2151). * * Replay itself is one click and unchanged; this is a second way to *supply* * the params, not a second replay implementation — Send dispatches through the * same `replayProtocolRequest` the plain Replay button does, so the same * method gate and the same "Can't replay" failure toast apply. */ export function EditReplayModal({ opened, method, params, onSend, onClose, }: EditReplayModalProps) { return ( ); }