Spaces:
Running
Running
import Editor from "@monaco-editor/react"; | |
import { ChevronUp, ChevronDown, Trash2, Power } from "lucide-react"; | |
import { useMemo } from "react"; | |
import { extractFunctionAndRenderer, generateSchemaFromCode } from "../utils"; | |
export interface Tool { | |
id: number; | |
name: string; | |
code: string; | |
enabled: boolean; | |
isCollapsed?: boolean; | |
renderer?: string; | |
} | |
interface ToolItemProps { | |
tool: Tool; | |
onToggleEnabled: () => void; | |
onToggleCollapsed: () => void; | |
onExpand: () => void; | |
onDelete: () => void; | |
onCodeChange: (newCode: string) => void; | |
} | |
const ToolItem: React.FC<ToolItemProps> = ({ | |
tool, | |
onToggleEnabled, | |
onToggleCollapsed, | |
onDelete, | |
onCodeChange, | |
}) => { | |
const { functionCode } = extractFunctionAndRenderer(tool.code); | |
const schema = useMemo( | |
() => generateSchemaFromCode(functionCode), | |
[functionCode], | |
); | |
return ( | |
<div | |
className={`bg-gray-700 rounded-lg p-4 transition-all ${!tool.enabled ? "opacity-50 grayscale" : ""}`} | |
> | |
<div | |
className="flex justify-between items-center cursor-pointer" | |
onClick={onToggleCollapsed} | |
> | |
<div> | |
<h3 className="text-lg font-bold text-teal-300 font-mono"> | |
{schema.name} | |
</h3> | |
<div className="text-xs text-gray-300 mt-1">{schema.description}</div> | |
</div> | |
<div className="flex items-center space-x-3"> | |
<button | |
onClick={(e) => { | |
e.stopPropagation(); | |
onToggleEnabled(); | |
}} | |
className={`p-1 rounded-full ${tool.enabled ? "text-green-400 hover:bg-green-900" : "text-red-400 hover:bg-red-900"}`} | |
> | |
<Power size={18} /> | |
</button> | |
<button | |
onClick={(e) => { | |
e.stopPropagation(); | |
onDelete(); | |
}} | |
className="p-2 text-gray-400 hover:text-red-500 hover:bg-gray-600 rounded-lg" | |
> | |
<Trash2 size={18} /> | |
</button> | |
<button | |
onClick={(e) => { | |
e.stopPropagation(); | |
onToggleCollapsed(); | |
}} | |
className="p-2 text-gray-400 hover:text-white" | |
> | |
{tool.isCollapsed ? ( | |
<ChevronDown size={20} /> | |
) : ( | |
<ChevronUp size={20} /> | |
)} | |
</button> | |
</div> | |
</div> | |
{!tool.isCollapsed && ( | |
<div className="mt-4 grid grid-cols-1 md:grid-cols-3 gap-4"> | |
<div className="md:col-span-2"> | |
<label className="text-sm font-bold text-gray-400"> | |
Implementation & Renderer | |
</label> | |
<div | |
className="mt-1 rounded-md overflow-visible border border-gray-600" | |
style={{ overflow: "visible" }} | |
> | |
<Editor | |
height="300px" | |
language="javascript" | |
theme="vs-dark" | |
value={tool.code} | |
onChange={(value) => onCodeChange(value || "")} | |
options={{ | |
minimap: { enabled: false }, | |
scrollbar: { verticalScrollbarSize: 10 }, | |
fontSize: 14, | |
lineDecorationsWidth: 0, | |
lineNumbersMinChars: 3, | |
scrollBeyondLastLine: false, | |
}} | |
/> | |
</div> | |
</div> | |
<div className="flex flex-col"> | |
<label className="text-sm font-bold text-gray-400"> | |
Generated Schema | |
</label> | |
<div className="mt-1 rounded-md flex-grow overflow-visible border border-gray-600"> | |
<Editor | |
height="300px" | |
language="json" | |
theme="vs-dark" | |
value={JSON.stringify(schema, null, 2)} | |
options={{ | |
readOnly: true, | |
minimap: { enabled: false }, | |
scrollbar: { verticalScrollbarSize: 10 }, | |
lineNumbers: "off", | |
glyphMargin: false, | |
folding: false, | |
lineDecorationsWidth: 0, | |
lineNumbersMinChars: 0, | |
scrollBeyondLastLine: false, | |
fontSize: 12, | |
}} | |
/> | |
</div> | |
</div> | |
</div> | |
)} | |
</div> | |
); | |
}; | |
export default ToolItem; | |