import { useCallback, useEffect, useState } from "react"; import { useNavigate } from "react-router-dom"; import { Icon } from "../components/icon"; import type { ToolType } from "../types/tool-type"; import type { ToolConfig } from "../types/tool-config"; import { listToolTypes } from "../api/tool_types"; import { createToolConfig, deleteToolConfig, listToolConfigs, updateToolConfig, } from "../api/tool_configs"; type ConfigStatus = "loading" | "ready" | "error"; export const ToolConfigsPage = () => { const navigate = useNavigate(); const [status, setStatus] = useState("loading"); const [toolTypes, setToolTypes] = useState([]); const [configs, setConfigs] = useState([]); const [selectedToolType, setSelectedToolType] = useState(""); const [showForm, setShowForm] = useState(false); const [editingConfig, setEditingConfig] = useState(null); const [formData, setFormData] = useState({ key: "", value: "", config_type: "env", file_path: "", }); const [saveStatus, setSaveStatus] = useState<"idle" | "saving" | "saved" | "error">("idle"); const loadData = useCallback(async () => { try { const [typesData, configsData] = await Promise.all([ listToolTypes(), listToolConfigs(), ]); setToolTypes(typesData); setConfigs(configsData); if (typesData.length > 0 && !selectedToolType) { setSelectedToolType(typesData[0].id); } setStatus("ready"); } catch { setStatus("error"); } }, [selectedToolType]); useEffect(() => { void loadData(); }, [loadData]); const handleSubmit = async (e: React.FormEvent) => { e.preventDefault(); setSaveStatus("saving"); try { const data = { tool_type_id: selectedToolType, key: formData.key, value: formData.value, config_type: formData.config_type, file_path: formData.config_type === "file" ? formData.file_path : undefined, }; if (editingConfig) { await updateToolConfig(editingConfig.id, data); } else { await createToolConfig(data); } setSaveStatus("saved"); setShowForm(false); setEditingConfig(null); setFormData({ key: "", value: "", config_type: "env", file_path: "" }); await loadData(); } catch { setSaveStatus("error"); } }; const handleEdit = (config: ToolConfig) => { setEditingConfig(config); setFormData({ key: config.key, value: config.value, config_type: config.config_type, file_path: config.file_path || "", }); setSelectedToolType(config.tool_type_id); setShowForm(true); }; const handleDelete = async (id: string) => { if (!window.confirm("Delete this config?")) return; try { await deleteToolConfig(id); await loadData(); } catch { // Error handled by UI state } }; const filteredConfigs = configs.filter( (c) => c.tool_type_id === selectedToolType ); const selectedTool = toolTypes.find((t) => t.id === selectedToolType); if (status === "loading") { return (

Tool Configurations

Loading...

); } if (status === "error") { return (

Tool Configurations

Failed to load configurations

); } return (

Settings

Tool Configurations

Manage environment variables and configuration files for your tools

{/* Tool Type Selector */}
{selectedTool && (

Category: {selectedTool.category} ยท Interfaces: {selectedTool.interfaces?.join(", ")}

)}
{/* Config List */}

Configuration Variables

{filteredConfigs.length === 0 ? (

No configurations for this tool yet.

) : (
{filteredConfigs.map((config) => (
{config.key} {config.config_type}

{config.config_type === "file" && config.file_path ? `File: ${config.file_path}` : "Environment variable"}

))}
)}
{/* Add/Edit Form */} {showForm && (

{editingConfig ? "Edit Config" : "Add Config"}

setFormData({ ...formData, key: e.target.value })} placeholder="e.g., OPENAI_API_KEY" className="form-input" required />
{formData.config_type === "file" && (
setFormData({ ...formData, file_path: e.target.value }) } placeholder="e.g., /app/config.json" className="form-input" required />
)}