Skip to content

Commit 463a784

Browse files
committed
fix checkbox input from UI
Signed-off-by: Madhav Kandukuri <[email protected]>
1 parent c0ae3d1 commit 463a784

File tree

1 file changed

+83
-37
lines changed

1 file changed

+83
-37
lines changed

mcpgateway/static/admin.js

Lines changed: 83 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -4484,33 +4484,53 @@ async function testTool(toolId) {
44844484
const wrapper = document.createElement("div");
44854485
wrapper.className = "flex items-center space-x-2";
44864486

4487-
const input = document.createElement("input");
4488-
input.name = keyValidation.value;
4489-
input.required =
4490-
schema.required && schema.required.includes(key);
4491-
input.className =
4492-
"mt-1 block w-full rounded-md border border-gray-300 shadow-sm focus:border-indigo-500 focus:ring-indigo-500 dark:bg-gray-900 text-gray-700 dark:text-gray-300 dark:border-gray-700 dark:focus:border-indigo-400 dark:focus:ring-indigo-400";
4493-
44944487
const itemTypes = Array.isArray(prop.items?.anyOf)
44954488
? prop.items.anyOf.map((t) => t.type)
44964489
: [prop.items?.type];
44974490

4491+
let input;
4492+
44984493
if (
44994494
itemTypes.includes("number") ||
45004495
itemTypes.includes("integer")
45014496
) {
4497+
input = document.createElement("input");
45024498
input.type = "number";
45034499
input.step = itemTypes.includes("integer")
45044500
? "1"
45054501
: "any";
45064502
} else if (itemTypes.includes("boolean")) {
4503+
const hiddenFalse = document.createElement("input");
4504+
hiddenFalse.type = "hidden";
4505+
hiddenFalse.name = keyValidation.value + "[]";
4506+
hiddenFalse.value = "false";
4507+
4508+
input = document.createElement("input");
45074509
input.type = "checkbox";
4510+
input.name = keyValidation.value + "[]";
45084511
input.value = "true";
4509-
input.checked = value === true || value === "true";
4512+
4513+
const checked = value === true || value === "true";
4514+
input.checked = checked;
4515+
hiddenFalse.disabled = checked;
4516+
4517+
input.addEventListener("change", () => {
4518+
hiddenFalse.disabled = input.checked;
4519+
});
4520+
4521+
wrapper.appendChild(hiddenFalse);
4522+
wrapper.appendChild(input);
45104523
} else {
4524+
input = document.createElement("input");
45114525
input.type = "text";
45124526
}
45134527

4528+
input.name = input.name || keyValidation.value + "[]";
4529+
input.required =
4530+
schema.required && schema.required.includes(key);
4531+
input.className =
4532+
"mt-1 block w-full rounded-md border border-gray-300 shadow-sm focus:border-indigo-500 focus:ring-indigo-500 dark:bg-gray-900 text-gray-700 dark:text-gray-300 dark:border-gray-700 dark:focus:border-indigo-400 dark:focus:ring-indigo-400";
4533+
45144534
if (
45154535
typeof value === "string" ||
45164536
typeof value === "number"
@@ -4528,7 +4548,11 @@ async function testTool(toolId) {
45284548
arrayContainer.removeChild(wrapper);
45294549
});
45304550

4531-
wrapper.appendChild(input);
4551+
// only append if not boolean (boolean branch already appended input above)
4552+
if (!itemTypes.includes("boolean")) {
4553+
wrapper.appendChild(input);
4554+
}
4555+
45324556
wrapper.appendChild(delBtn);
45334557
return wrapper;
45344558
}
@@ -4560,44 +4584,66 @@ async function testTool(toolId) {
45604584
fieldDiv.appendChild(arrayContainer);
45614585
fieldDiv.appendChild(addBtn);
45624586
} else {
4563-
// Input field with validation (with multiline support)
45644587
let fieldInput;
4565-
const isTextType = prop.type === "text";
4566-
if (isTextType) {
4567-
fieldInput = document.createElement("textarea");
4568-
fieldInput.rows = 4;
4569-
} else {
4588+
4589+
if (prop.type === "boolean") {
4590+
// Hidden "false" to ensure a value when unchecked
4591+
const hiddenFalse = document.createElement("input");
4592+
hiddenFalse.type = "hidden";
4593+
hiddenFalse.name = keyValidation.value;
4594+
hiddenFalse.value = "false";
4595+
4596+
// Visible checkbox (submits "true" when checked)
45704597
fieldInput = document.createElement("input");
4571-
if (prop.type === "number" || prop.type === "integer") {
4598+
fieldInput.type = "checkbox";
4599+
fieldInput.name = keyValidation.value;
4600+
fieldInput.value = "true";
4601+
4602+
fieldInput.required =
4603+
schema.required && schema.required.includes(key);
4604+
fieldInput.className =
4605+
"mt-1 h-4 w-4 text-indigo-600 dark:text-indigo-200 border border-gray-300 rounded";
4606+
4607+
// set defaults
4608+
const checked = prop.default === true;
4609+
fieldInput.checked = checked;
4610+
hiddenFalse.disabled = checked;
4611+
4612+
fieldInput.addEventListener("change", () => {
4613+
hiddenFalse.disabled = fieldInput.checked;
4614+
});
4615+
4616+
// append both (hidden first)
4617+
fieldDiv.appendChild(hiddenFalse);
4618+
fieldDiv.appendChild(fieldInput);
4619+
} else {
4620+
// Non-boolean handling
4621+
if (prop.type === "text") {
4622+
fieldInput = document.createElement("textarea");
4623+
fieldInput.rows = 4;
4624+
} else if (
4625+
prop.type === "number" ||
4626+
prop.type === "integer"
4627+
) {
4628+
fieldInput = document.createElement("input");
45724629
fieldInput.type = "number";
4573-
} else if (prop.type === "boolean") {
4574-
fieldInput.type = "checkbox";
45754630
} else {
45764631
fieldInput = document.createElement("textarea");
45774632
fieldInput.rows = 1;
45784633
}
4579-
}
45804634

4581-
fieldInput.name = keyValidation.value;
4582-
fieldInput.required =
4583-
schema.required && schema.required.includes(key);
4584-
fieldInput.className =
4585-
prop.type === "boolean"
4586-
? "mt-1 h-4 w-4 text-indigo-600 dark:text-indigo-200 border border-gray-300 rounded"
4587-
: "mt-1 block w-full rounded-md border border-gray-300 shadow-sm focus:border-indigo-500 focus:ring-indigo-500 dark:bg-gray-900 text-gray-700 dark:text-gray-300 dark:border-gray-700 dark:focus:border-indigo-400 dark:focus:ring-indigo-400";
4588-
4589-
// Set default values here
4590-
if (prop.default !== undefined) {
4591-
if (fieldInput.type === "checkbox") {
4592-
fieldInput.checked = prop.default === true;
4593-
} else if (isTextType) {
4594-
fieldInput.value = prop.default;
4595-
} else {
4635+
fieldInput.name = keyValidation.value;
4636+
fieldInput.required =
4637+
schema.required && schema.required.includes(key);
4638+
fieldInput.className =
4639+
"mt-1 block w-full rounded-md border border-gray-300 shadow-sm focus:border-indigo-500 focus:ring-indigo-500 dark:bg-gray-900 text-gray-700 dark:text-gray-300 dark:border-gray-700 dark:focus:border-indigo-400 dark:focus:ring-indigo-400";
4640+
4641+
if (prop.default !== undefined) {
45964642
fieldInput.value = prop.default;
45974643
}
4598-
}
45994644

4600-
fieldDiv.appendChild(fieldInput);
4645+
fieldDiv.appendChild(fieldInput);
4646+
}
46014647
}
46024648

46034649
container.appendChild(fieldDiv);
@@ -9156,4 +9202,4 @@ async function testA2AAgent(agentId, agentName, endpointUrl) {
91569202
}
91579203

91589204
// Expose A2A test function to global scope
9159-
window.testA2AAgent = testA2AAgent;
9205+
window.testA2AAgent = testA2AAgent;

0 commit comments

Comments
 (0)