Skip to content

Commit 6d691e9

Browse files
authored
Merge pull request #842 from olaservo/add-dropdowns-for-enums
Add enum parameter support in ToolsTab component and corresponding tests
2 parents 5c3afda + 8bfd164 commit 6d691e9

File tree

2 files changed

+101
-0
lines changed

2 files changed

+101
-0
lines changed

client/src/components/ToolsTab.tsx

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,13 @@ import { Input } from "@/components/ui/input";
55
import { Label } from "@/components/ui/label";
66
import { TabsContent } from "@/components/ui/tabs";
77
import { Textarea } from "@/components/ui/textarea";
8+
import {
9+
Select,
10+
SelectContent,
11+
SelectItem,
12+
SelectTrigger,
13+
SelectValue,
14+
} from "@/components/ui/select";
815
import DynamicJsonForm, { DynamicJsonFormRef } from "./DynamicJsonForm";
916
import type { JsonValue, JsonSchemaType } from "@/utils/jsonUtils";
1017
import {
@@ -182,6 +189,42 @@ const ToolsTab = ({
182189
{prop.description || "Toggle this option"}
183190
</label>
184191
</div>
192+
) : prop.type === "string" && prop.enum ? (
193+
<Select
194+
value={
195+
params[key] === undefined
196+
? ""
197+
: String(params[key])
198+
}
199+
onValueChange={(value) => {
200+
if (value === "") {
201+
setParams({
202+
...params,
203+
[key]: undefined,
204+
});
205+
} else {
206+
setParams({
207+
...params,
208+
[key]: value,
209+
});
210+
}
211+
}}
212+
>
213+
<SelectTrigger id={key} className="mt-1">
214+
<SelectValue
215+
placeholder={
216+
prop.description || "Select an option"
217+
}
218+
/>
219+
</SelectTrigger>
220+
<SelectContent>
221+
{prop.enum.map((option) => (
222+
<SelectItem key={option} value={option}>
223+
{option}
224+
</SelectItem>
225+
))}
226+
</SelectContent>
227+
</Select>
185228
) : prop.type === "string" ? (
186229
<Textarea
187230
id={key}

client/src/components/__tests__/ToolsTab.test.tsx

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -638,6 +638,64 @@ describe("ToolsTab", () => {
638638
});
639639
});
640640

641+
describe("Enum Parameters", () => {
642+
const toolWithEnumParam: Tool = {
643+
name: "enumTool",
644+
description: "Tool with enum parameter",
645+
inputSchema: {
646+
type: "object" as const,
647+
properties: {
648+
format: {
649+
type: "string" as const,
650+
enum: ["json", "xml", "csv", "yaml"],
651+
description: "Output format",
652+
},
653+
},
654+
},
655+
};
656+
657+
beforeEach(() => {
658+
// Mock scrollIntoView for Radix UI Select
659+
Element.prototype.scrollIntoView = jest.fn();
660+
});
661+
662+
it("should render enum parameter as dropdown", () => {
663+
renderToolsTab({
664+
tools: [toolWithEnumParam],
665+
selectedTool: toolWithEnumParam,
666+
});
667+
668+
// Should render a select button instead of textarea
669+
const selectTrigger = screen.getByRole("combobox", { name: /format/i });
670+
expect(selectTrigger).toBeInTheDocument();
671+
});
672+
673+
it("should render non-enum string parameter as textarea", () => {
674+
const toolWithStringParam: Tool = {
675+
name: "stringTool",
676+
description: "Tool with regular string parameter",
677+
inputSchema: {
678+
type: "object" as const,
679+
properties: {
680+
text: {
681+
type: "string" as const,
682+
description: "Some text input",
683+
},
684+
},
685+
},
686+
};
687+
688+
renderToolsTab({
689+
tools: [toolWithStringParam],
690+
selectedTool: toolWithStringParam,
691+
});
692+
693+
// Should render textarea, not select
694+
expect(screen.queryByRole("combobox")).not.toBeInTheDocument();
695+
expect(screen.getByRole("textbox")).toBeInTheDocument();
696+
});
697+
});
698+
641699
describe("JSON Validation Integration", () => {
642700
const toolWithJsonParams: Tool = {
643701
name: "jsonTool",

0 commit comments

Comments
 (0)