From 67e11edb48de694e0ae0e2090e83b86435fd5dbf Mon Sep 17 00:00:00 2001 From: simran-tavro Date: Fri, 5 Jun 2026 18:05:25 +0530 Subject: [PATCH] Updated edit functionality, removed home menu item and duplicate AI Assistant titles --- tavro_app/src/components/AgentHeader.tsx | 80 ++++- .../src/components/AgentIdentificationTab.tsx | 128 ++++++- tavro_app/src/components/AgentView.tsx | 54 ++- tavro_app/src/components/ChatPanel.tsx | 1 - tavro_app/src/components/Layout.tsx | 13 +- tavro_app/src/components/UseCaseView.tsx | 339 ++++++++++++++++-- tavro_app/src/pages/AgentViewPage.tsx | 245 ++++++++++--- .../src/pages/BusinessApplicationViewPage.tsx | 228 ++++++++++-- .../src/pages/BusinessProcessViewPage.tsx | 229 ++++++++++-- tavro_app/src/pages/IntegrationViewPage.tsx | 227 +++++++++--- tavro_app/src/pages/UseCaseViewPage.tsx | 212 +++++++++-- 11 files changed, 1472 insertions(+), 284 deletions(-) diff --git a/tavro_app/src/components/AgentHeader.tsx b/tavro_app/src/components/AgentHeader.tsx index d5245fc..4b2eb67 100644 --- a/tavro_app/src/components/AgentHeader.tsx +++ b/tavro_app/src/components/AgentHeader.tsx @@ -1,9 +1,22 @@ import React from 'react'; import { AgentData } from '../types/agent'; -import { Bot, ExternalLink, Globe, BookOpen, ShieldAlert, CheckCircle2 } from 'lucide-react'; +import { Bot, ExternalLink, Globe, BookOpen, ShieldAlert, CheckCircle2, Loader2 } from 'lucide-react'; import { getAgentRiskLevel } from '../utils/agentRisk'; -interface AgentHeaderProps { agent: AgentData; } +type AgentInlineField = 'name' | 'description' | 'instruction'; + +interface AgentHeaderProps { + agent: AgentData; + isEditing?: boolean; + editName?: string; + onEditNameChange?: (v: string) => void; + inlineEdit?: { field: AgentInlineField; value: string } | null; + inlineSaving?: AgentInlineField | null; + onStartInlineEdit?: (field: AgentInlineField) => void; + onInlineValueChange?: (value: string) => void; + onSaveInlineEdit?: () => void; + onCancelInlineEdit?: () => void; +} const Badge: React.FC<{ text: string; color?: 'blue' | 'emerald' | 'amber' | 'rose' | 'slate' }> = ({ text, color = 'slate' }) => { const cls = { @@ -16,7 +29,18 @@ const Badge: React.FC<{ text: string; color?: 'blue' | 'emerald' | 'amber' | 'ro return {text}; }; -const AgentHeader: React.FC = ({ agent }) => { +const AgentHeader: React.FC = ({ + agent, + isEditing, + editName, + onEditNameChange, + inlineEdit, + inlineSaving, + onStartInlineEdit, + onInlineValueChange, + onSaveInlineEdit, + onCancelInlineEdit, +}) => { const id = agent.identification; const caps = agent.capabilities; @@ -44,6 +68,9 @@ const AgentHeader: React.FC = ({ agent }) => { : riskLevel === 'medium' ? 'text-amber-600' : 'text-emerald-600'; + const isInlineName = inlineEdit?.field === 'name'; + const isSavingName = inlineSaving === 'name'; + const nameSaveDisabled = isSavingName || !inlineEdit?.value.trim(); return (
@@ -51,8 +78,51 @@ const AgentHeader: React.FC = ({ agent }) => {
-
-

{agent.name}

+
+ {isEditing ? ( + onEditNameChange?.(e.target.value)} + className="text-2xl font-bold text-slate-800 tracking-tight w-full border-b-2 border-blue-400 bg-transparent outline-none pb-0.5" + /> + ) : isInlineName && inlineEdit ? ( +
+ onInlineValueChange?.(e.target.value)} + className="text-2xl font-bold text-slate-800 tracking-tight flex-1 border-b-2 border-blue-400 bg-transparent outline-none pb-0.5" + autoFocus + /> + + +
+ ) : ( +

onStartInlineEdit?.('name')} + title="Double-click to edit" + className="text-2xl font-bold text-slate-800 tracking-tight break-words cursor-text rounded-lg hover:bg-blue-50/50 transition-colors" + > + {agent.name} +

+ )}
{id?.agent_id || 'N/A'} diff --git a/tavro_app/src/components/AgentIdentificationTab.tsx b/tavro_app/src/components/AgentIdentificationTab.tsx index 60caf56..feaa903 100644 --- a/tavro_app/src/components/AgentIdentificationTab.tsx +++ b/tavro_app/src/components/AgentIdentificationTab.tsx @@ -1,15 +1,67 @@ import React, { useEffect, useRef, useState } from 'react'; import { AgentData } from '../types/agent'; -import { User, Tag, ChevronDown, ChevronUp } from 'lucide-react'; +import { User, Tag, ChevronDown, ChevronUp, Loader2 } from 'lucide-react'; -interface AgentIdentificationTabProps { agent: AgentData; } +type AgentInlineField = 'name' | 'description' | 'instruction'; -export const AgentIdentificationTab: React.FC = ({ agent }) => { +interface AgentIdentificationTabProps { + agent: AgentData; + isEditing?: boolean; + editDescription?: string; + onEditDescriptionChange?: (v: string) => void; + editInstruction?: string; + onEditInstructionChange?: (v: string) => void; + inlineEdit?: { field: AgentInlineField; value: string } | null; + inlineSaving?: AgentInlineField | null; + onStartInlineEdit?: (field: AgentInlineField) => void; + onInlineValueChange?: (value: string) => void; + onSaveInlineEdit?: () => void; + onCancelInlineEdit?: () => void; +} + +export const AgentIdentificationTab: React.FC = ({ + agent, isEditing, + editDescription, onEditDescriptionChange, + editInstruction, onEditInstructionChange, + inlineEdit, inlineSaving, onStartInlineEdit, + onInlineValueChange, onSaveInlineEdit, onCancelInlineEdit, +}) => { const [instrOpen, setInstrOpen] = useState(false); const [instrOverflow, setInstrOverflow] = useState(false); const instructionContainerRef = useRef(null); const id = agent.identification; const COLLAPSED_MAX_HEIGHT_PX = 128; // max-h-32 + const isInlineDescription = inlineEdit?.field === 'description'; + const isInlineInstruction = inlineEdit?.field === 'instruction'; + + const renderInlineActions = (field: AgentInlineField) => { + const isSaving = inlineSaving === field; + const isBlank = !inlineEdit?.value.trim(); + const saveDisabled = isSaving || isBlank; + + return ( +
+ + +
+ ); + }; useEffect(() => { const node = instructionContainerRef.current; @@ -26,9 +78,33 @@ export const AgentIdentificationTab: React.FC = ({ Identification & Role -

- {agent.description} -

+ {isEditing ? ( +