import React, { ChangeEvent } from 'react'; import { Input } from '@/components/ui/input'; import { Textarea } from '@/components/ui/textarea'; import { Checkbox } from '@/components/ui/checkbox'; import { Label } from '@/components/ui/label'; import { Button } from '@/components/ui/button'; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from '@/components/ui/select'; import { Copy, Share2, Zap } from 'lucide-react'; import type { McpTool } from '@/components/hooks/useServers'; // Infer the property schema type from the tool's input schema type JsonSchemaProperty = NonNullable['properties']>[string]; interface ToolInputFormProps { tool: McpTool; inputs: Record; errors: Record; isLoading: boolean; onInputChange: ( name: string, value: any, type?: 'string' | 'number' | 'integer' | 'boolean' | 'object' | 'array' ) => void; onSubmit: () => void; onCopyConfig?: () => void; onShareConfig?: () => void; } interface ToolTemplate { name: string; description: string; apply: (tool: McpTool) => Record; } const toolTemplates: ToolTemplate[] = [ { name: 'Quick Test', description: 'Fill with test values', apply: (tool: McpTool) => { const defaults: Record = {}; if (tool.inputSchema?.properties) { Object.entries(tool.inputSchema.properties).forEach( ([key, prop]: [string, any]) => { if (prop.type === 'string') defaults[key] = `test-${key}`; else if (prop.type === 'number') defaults[key] = 42; else if (prop.type === 'boolean') defaults[key] = true; else if (prop.type === 'object') defaults[key] = '{"example": "value"}'; else if (prop.type === 'array') defaults[key] = '["example"]'; } ); } return defaults; }, }, { name: 'Required Only', description: 'Fill only required fields', apply: (tool: McpTool) => { const defaults: Record = {}; if (tool.inputSchema?.properties && tool.inputSchema?.required) { tool.inputSchema.required.forEach((key: string) => { const prop = tool.inputSchema!.properties![key]; if (prop.type === 'string') defaults[key] = ''; else if (prop.type === 'number') defaults[key] = ''; else if (prop.type === 'boolean') defaults[key] = false; else if (prop.type === 'object') defaults[key] = '{}'; else if (prop.type === 'array') defaults[key] = '[]'; }); } return defaults; }, }, { name: 'Clear All', description: 'Clear all fields', apply: () => ({}), }, ]; export function ToolInputForm({ tool, inputs, errors, isLoading, onInputChange, onSubmit, onCopyConfig, onShareConfig, }: ToolInputFormProps) { const hasInputs = tool.inputSchema?.properties && Object.keys(tool.inputSchema.properties).length > 0; const renderInput = (key: string, prop: JsonSchemaProperty) => { const isRequired = tool.inputSchema?.required?.includes(key); const errorMsg = errors[key]; const baseInputClassName = `w-full ${errorMsg ? 'border-destructive focus-visible:ring-destructive' : ''}`; // Enum select if (prop.enum && Array.isArray(prop.enum)) { const isEnumBoolean = prop.enum.every( (v: string | number | boolean) => typeof v === 'boolean' ); const isEnumNumeric = prop.enum.every( (v: string | number | boolean) => typeof v === 'number' ); return ( ); } // Boolean checkbox if (prop.type === 'boolean') { return ( onInputChange(key, checked, prop.type)} disabled={isLoading} className={errorMsg ? 'border-destructive ring-destructive' : ''} /> ); } // Object/Array textarea if (prop.type === 'object' || prop.type === 'array') { return (