From bcccd49ec0d633c010872019abc280d73bd2b598 Mon Sep 17 00:00:00 2001 From: Ulysses Date: Thu, 7 Aug 2025 10:34:29 +0700 Subject: [PATCH] feat: Add edit functionality for agents in modal - Added Edit button to each agent in the Agent Management modal - Implemented event system to pass agent data to CreateAgent component - Modified CreateAgent to accept editing data from localStorage - Added proper cleanup of localStorage after editing Closes #259 - Users can now edit existing agents --- src/components/CreateAgent.tsx | 40 +++++++++++++++++++++++++++------- src/components/TabContent.tsx | 14 ++++++++++++ 2 files changed, 46 insertions(+), 8 deletions(-) diff --git a/src/components/CreateAgent.tsx b/src/components/CreateAgent.tsx index 3c1ffec..1dfa1e0 100644 --- a/src/components/CreateAgent.tsx +++ b/src/components/CreateAgent.tsx @@ -43,17 +43,41 @@ export const CreateAgent: React.FC = ({ onAgentCreated, className, }) => { - const [name, setName] = useState(agent?.name || ""); - const [selectedIcon, setSelectedIcon] = useState((agent?.icon as AgentIconName) || "bot"); - const [systemPrompt, setSystemPrompt] = useState(agent?.system_prompt || ""); - const [defaultTask, setDefaultTask] = useState(agent?.default_task || ""); - const [model, setModel] = useState(agent?.model || "sonnet"); + // Check for editing agent in localStorage + const [editingAgent, setEditingAgent] = useState(() => { + if (agent) return agent; + const stored = window.localStorage.getItem('editingAgent'); + if (stored) { + // Don't remove immediately - will clean up after component mounts + return JSON.parse(stored); + } + return undefined; + }); + + // Clean up localStorage after component mounts + React.useEffect(() => { + if (editingAgent && !agent) { + // Small delay to ensure state is set + const timer = setTimeout(() => { + window.localStorage.removeItem('editingAgent'); + }, 500); + return () => clearTimeout(timer); + } + }, [editingAgent, agent]); + + const agentData = editingAgent || agent; + + const [name, setName] = useState(agentData?.name || ""); + const [selectedIcon, setSelectedIcon] = useState((agentData?.icon as AgentIconName) || "bot"); + const [systemPrompt, setSystemPrompt] = useState(agentData?.system_prompt || ""); + const [defaultTask, setDefaultTask] = useState(agentData?.default_task || ""); + const [model, setModel] = useState(agentData?.model || "sonnet"); const [saving, setSaving] = useState(false); const [error, setError] = useState(null); const [toast, setToast] = useState<{ message: string; type: "success" | "error" } | null>(null); const [showIconPicker, setShowIconPicker] = useState(false); - const isEditMode = !!agent; + const isEditMode = !!agentData; const handleSave = async () => { if (!name.trim()) { @@ -70,9 +94,9 @@ export const CreateAgent: React.FC = ({ setSaving(true); setError(null); - if (isEditMode && agent.id) { + if (isEditMode && agentData.id) { await api.updateAgent( - agent.id, + agentData.id, name, selectedIcon, systemPrompt, diff --git a/src/components/TabContent.tsx b/src/components/TabContent.tsx index cb5ca82..34fc9e2 100644 --- a/src/components/TabContent.tsx +++ b/src/components/TabContent.tsx @@ -357,6 +357,18 @@ export const TabContent: React.FC = () => { createImportAgentTab(); }; + const handleOpenEditAgentTab = (event: CustomEvent) => { + const { agent } = event.detail; + // Store agent in localStorage temporarily + window.localStorage.setItem('editingAgent', JSON.stringify(agent)); + // Create a new create-agent tab + const tabId = createCreateAgentTab(); + // Update the tab title to show it's editing + setTimeout(() => { + updateTab(tabId, { title: `Edit: ${agent.name}` }); + }, 100); + }; + const handleCloseTab = (event: CustomEvent) => { const { tabId } = event.detail; closeTab(tabId); @@ -387,6 +399,7 @@ export const TabContent: React.FC = () => { window.addEventListener('open-agent-execution', handleOpenAgentExecution as EventListener); window.addEventListener('open-create-agent-tab', handleOpenCreateAgentTab); window.addEventListener('open-import-agent-tab', handleOpenImportAgentTab); + window.addEventListener('open-edit-agent-tab', handleOpenEditAgentTab as EventListener); window.addEventListener('close-tab', handleCloseTab as EventListener); window.addEventListener('claude-session-selected', handleClaudeSessionSelected as EventListener); return () => { @@ -395,6 +408,7 @@ export const TabContent: React.FC = () => { window.removeEventListener('open-agent-execution', handleOpenAgentExecution as EventListener); window.removeEventListener('open-create-agent-tab', handleOpenCreateAgentTab); window.removeEventListener('open-import-agent-tab', handleOpenImportAgentTab); + window.removeEventListener('open-edit-agent-tab', handleOpenEditAgentTab as EventListener); window.removeEventListener('close-tab', handleCloseTab as EventListener); window.removeEventListener('claude-session-selected', handleClaudeSessionSelected as EventListener); };