Add version save modal to agent details

Implement a modal for saving agent versions on the agent details screen. The modal allows users to input version notes, select the version type (major, minor, or patch) with explanations for each, and includes cancel and save buttons. The save button is disabled until notes are entered.
This commit is contained in:
gpt-engineer-app[bot]
2025-11-07 19:48:45 +00:00
parent 1f2f734fd8
commit f87685e014
2 changed files with 138 additions and 4 deletions
+126
View File
@@ -0,0 +1,126 @@
import { Button } from "@/components/ui/button";
import {
Dialog,
DialogContent,
DialogDescription,
DialogFooter,
DialogHeader,
DialogTitle,
} from "@/components/ui/dialog";
import { Textarea } from "@/components/ui/textarea";
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
import { Label } from "@/components/ui/label";
import { useState } from "react";
import { AlertCircle } from "lucide-react";
interface SaveVersionDialogProps {
open: boolean;
onOpenChange: (open: boolean) => void;
onSave: (versionType: "major" | "minor" | "patch", notes: string) => void;
}
export function SaveVersionDialog({
open,
onOpenChange,
onSave,
}: SaveVersionDialogProps) {
const [versionType, setVersionType] = useState<"major" | "minor" | "patch">("minor");
const [notes, setNotes] = useState("");
const handleSave = () => {
onSave(versionType, notes);
setNotes("");
setVersionType("minor");
onOpenChange(false);
};
const versionInfo = {
major: {
title: "Major",
description: "Use quando fizer mudanças significativas ou incompatíveis no comportamento do agente",
example: "Ex: Mudança completa na personalidade ou objetivo do agente",
},
minor: {
title: "Minor",
description: "Use quando adicionar funcionalidades ou melhorias que não quebram o comportamento atual",
example: "Ex: Adicionar novas instruções ou melhorar respostas",
},
patch: {
title: "Patch",
description: "Use para pequenos ajustes, correções ou refinamentos",
example: "Ex: Correção de erros gramaticais ou pequenos ajustes de tom",
},
};
return (
<Dialog open={open} onOpenChange={onOpenChange}>
<DialogContent className="max-w-2xl">
<DialogHeader>
<DialogTitle>Salvar Nova Versão</DialogTitle>
<DialogDescription>
Documente as alterações realizadas no agente
</DialogDescription>
</DialogHeader>
<div className="space-y-4">
{/* Tipo de Versão */}
<div className="space-y-2">
<Label htmlFor="version-type">Tipo de Alteração</Label>
<Select
value={versionType}
onValueChange={(value: "major" | "minor" | "patch") => setVersionType(value)}
>
<SelectTrigger id="version-type">
<SelectValue />
</SelectTrigger>
<SelectContent>
<SelectItem value="major">Major - Mudanças Significativas</SelectItem>
<SelectItem value="minor">Minor - Novas Funcionalidades</SelectItem>
<SelectItem value="patch">Patch - Correções e Ajustes</SelectItem>
</SelectContent>
</Select>
</div>
{/* Explicação do tipo selecionado */}
<div className="rounded-lg bg-muted/50 p-4 space-y-2">
<div className="flex items-start gap-2">
<AlertCircle className="h-4 w-4 text-muted-foreground mt-0.5" />
<div className="space-y-1 text-sm">
<p className="font-medium text-foreground">
{versionInfo[versionType].title}
</p>
<p className="text-muted-foreground">
{versionInfo[versionType].description}
</p>
<p className="text-xs text-muted-foreground italic">
{versionInfo[versionType].example}
</p>
</div>
</div>
</div>
{/* Notas da Versão */}
<div className="space-y-2">
<Label htmlFor="version-notes">Notas da Versão</Label>
<Textarea
id="version-notes"
value={notes}
onChange={(e) => setNotes(e.target.value)}
placeholder="Descreva as alterações realizadas nesta versão..."
className="min-h-[100px]"
/>
</div>
</div>
<DialogFooter>
<Button variant="outline" onClick={() => onOpenChange(false)}>
Cancelar
</Button>
<Button onClick={handleSave} disabled={!notes.trim()}>
Salvar Versão
</Button>
</DialogFooter>
</DialogContent>
</Dialog>
);
}
+12 -4
View File
@@ -8,12 +8,14 @@ import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@
import { ArrowLeft, Save, History, Power } from "lucide-react";
import { useToast } from "@/hooks/use-toast";
import { VersionHistoryDialog } from "@/components/agents/VersionHistoryDialog";
import { SaveVersionDialog } from "@/components/agents/SaveVersionDialog";
export default function AgentDetails() {
const { id } = useParams();
const navigate = useNavigate();
const { toast } = useToast();
const [isHistoryOpen, setIsHistoryOpen] = useState(false);
const [isSaveVersionOpen, setIsSaveVersionOpen] = useState(false);
// Mock data - substituir por dados reais do backend
const [agent, setAgent] = useState<{
@@ -72,12 +74,12 @@ export default function AgentDetails() {
{ value: "openai/gpt-5-nano", label: "OpenAI GPT-5 Nano" },
];
const handleSave = () => {
const handleSave = (versionType: "major" | "minor" | "patch", notes: string) => {
// TODO: Implementar salvamento no backend
console.log("Saving agent:", agent);
console.log("Saving agent:", agent, "Version type:", versionType, "Notes:", notes);
toast({
title: "Agente atualizado",
description: "As alterações foram salvas com sucesso.",
description: `Nova versão ${versionType} salva com sucesso.`,
});
};
@@ -136,7 +138,7 @@ export default function AgentDetails() {
<Power className="h-4 w-4" />
{agent.status === "active" ? "Desativar" : "Ativar"}
</Button>
<Button className="gap-2" onClick={handleSave}>
<Button className="gap-2" onClick={() => setIsSaveVersionOpen(true)}>
<Save className="h-4 w-4" />
Salvar Alterações
</Button>
@@ -197,6 +199,12 @@ export default function AgentDetails() {
agentName={agent.name}
versions={versions}
/>
<SaveVersionDialog
open={isSaveVersionOpen}
onOpenChange={setIsSaveVersionOpen}
onSave={handleSave}
/>
</div>
);
}