* feat(web): add Mantine clear buttons to text inputs app-wide (#1333) Add a clear (×) affordance to every user-editable text input across the web client so a populated field can be reset in one click. - Autocomplete: enable `clearable` by default via the theme (`theme/Autocomplete.ts`) — covers the prompt-argument and resource-template variable autocomplete branches. - TextInput / Textarea: Mantine v8 does not expose a public `clearable` prop on these primitives (only the combobox-based components do), so add the clear button manually via `rightSection` + `CloseButton` (aria-label="Clear") shown only when the field has a value, wired to reset the field's controlled value to "". Applied to sidebar search inputs (prompts, tools, apps, tasks, history, resources, network, logs), prompt-argument and resource-template variable inputs, the sampling response/model fields, server config & settings forms, roots table, schema form, experimental features panel, and the server.json import panel. Read-only/display Textareas (OutputValidationModal, UrlElicitationErrorModal) are intentionally left untouched. Tests cover the clear behavior on representative inputs from each category (sidebar search, prompt argument, resource-template variable, sampling response, plus the config/settings forms). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(web): disable ServerConfigModal clear buttons while submitting Address review #2 on #1448: the clear CloseButton sat in `rightSection` with `rightSectionPointerEvents="auto"`, so it stayed clickable even while the field was `disabled={submitting}`, letting a user wipe a field mid-submit. Forward `disabled={submitting}` to each clear button so it locks together with its input. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * refactor(web): remove redundant Auto-respond from SamplingRequestPanel The sampling modal pre-loads its draft with the default stub result, and "Send Response" sends that draft — so on an untouched form "Auto-respond" did exactly the same thing as "Send Response", just with a fresh copy of the same defaults. Drop the redundant button and its `onAutoRespond` prop; "Send Response" now covers both the unedited (stub) and edited cases. The InlineSamplingRequest variant keeps its Auto-respond button — there it is the quick path versus "Edit & Send" (which opens this editable modal), not a duplicate of an adjacent send action. Updated PendingClientRequestModal wiring, stories, and tests accordingly. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
62d442b073
commit
0890c7509a
2 changed files with 805 additions and 28 deletions
|
|
@ -196,6 +196,40 @@ describe("ImportServerJsonPanel", () => {
|
|||
expect(onServerNameChange).toHaveBeenCalledWith("X");
|
||||
});
|
||||
|
||||
it("clears the paste textarea, env-var, and name-override fields via Clear buttons", async () => {
|
||||
const user = userEvent.setup();
|
||||
const onJsonChange = vi.fn();
|
||||
const onEnvVarChange = vi.fn();
|
||||
const onServerNameChange = vi.fn();
|
||||
const envVars: EnvVarInfo[] = [
|
||||
{ name: "DEBUG", required: false, value: "true" },
|
||||
];
|
||||
renderWithMantine(
|
||||
<ImportServerJsonPanel
|
||||
{...baseHandlers}
|
||||
onJsonChange={onJsonChange}
|
||||
onEnvVarChange={onEnvVarChange}
|
||||
onServerNameChange={onServerNameChange}
|
||||
draft={{
|
||||
rawText: "{}",
|
||||
envOverrides: {},
|
||||
nameOverride: "Custom Name",
|
||||
}}
|
||||
validation={[]}
|
||||
envVars={envVars}
|
||||
/>,
|
||||
);
|
||||
// DOM order: paste textarea, env-var input, name-override input.
|
||||
const clearButtons = screen.getAllByRole("button", { name: "Clear" });
|
||||
expect(clearButtons).toHaveLength(3);
|
||||
await user.click(clearButtons[0]);
|
||||
expect(onJsonChange).toHaveBeenCalledWith("");
|
||||
await user.click(clearButtons[1]);
|
||||
expect(onEnvVarChange).toHaveBeenCalledWith("DEBUG", "");
|
||||
await user.click(clearButtons[2]);
|
||||
expect(onServerNameChange).toHaveBeenCalledWith("");
|
||||
});
|
||||
|
||||
it("renders the existing nameOverride value", () => {
|
||||
renderWithMantine(
|
||||
<ImportServerJsonPanel
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
import {
|
||||
Button,
|
||||
CloseButton,
|
||||
Divider,
|
||||
Group,
|
||||
Radio,
|
||||
|
|
@ -88,6 +89,12 @@ export function ImportServerJsonPanel({
|
|||
autosize
|
||||
minRows={8}
|
||||
maxRows={15}
|
||||
rightSectionPointerEvents="auto"
|
||||
rightSection={
|
||||
draft.rawText ? (
|
||||
<CloseButton aria-label="Clear" onClick={() => onJsonChange("")} />
|
||||
) : null
|
||||
}
|
||||
/>
|
||||
|
||||
<Divider />
|
||||
|
|
@ -139,6 +146,15 @@ export function ImportServerJsonPanel({
|
|||
onChange={(e) =>
|
||||
onEnvVarChange(envVar.name, e.currentTarget.value)
|
||||
}
|
||||
rightSectionPointerEvents="auto"
|
||||
rightSection={
|
||||
envVar.value ? (
|
||||
<CloseButton
|
||||
aria-label="Clear"
|
||||
onClick={() => onEnvVarChange(envVar.name, "")}
|
||||
/>
|
||||
) : null
|
||||
}
|
||||
/>
|
||||
))}
|
||||
</>
|
||||
|
|
@ -150,6 +166,15 @@ export function ImportServerJsonPanel({
|
|||
label="Server Name (optional override)"
|
||||
value={draft.nameOverride ?? ""}
|
||||
onChange={(e) => onServerNameChange(e.currentTarget.value)}
|
||||
rightSectionPointerEvents="auto"
|
||||
rightSection={
|
||||
draft.nameOverride ? (
|
||||
<CloseButton
|
||||
aria-label="Clear"
|
||||
onClick={() => onServerNameChange("")}
|
||||
/>
|
||||
) : null
|
||||
}
|
||||
/>
|
||||
|
||||
<Group justify="flex-end">
|
||||
|
|
|
|||
Loading…
Reference in a new issue