flowmind-studio / components /workflow /WorkflowMetaPanel.tsx
Caner Giden
fixed
8c55e35
Raw
History Blame Contribute Delete
6.03 kB
"use client";
import { useState, useEffect } from "react";
import { useRouter } from "next/navigation";
import { useWorkflowStore } from "@/store/workflowStore";
import Button from "@/components/ui/Button";
import Input from "@/components/ui/Input";
import Textarea from "@/components/ui/Textarea";
import Badge from "@/components/ui/Badge";
import { Save, Trash2, Play, ArrowLeft, Power } from "lucide-react";
export default function WorkflowMetaPanel() {
const router = useRouter();
const {
currentWorkflow,
setCurrentWorkflow,
saveWorkflow,
updateWorkflow,
deleteWorkflow,
setIsRunning,
clearRunLogs,
isLoading,
} = useWorkflowStore();
const [name, setName] = useState("");
const [description, setDescription] = useState("");
const [isActive, setIsActive] = useState(false);
useEffect(() => {
if (currentWorkflow) {
setName(currentWorkflow.name);
setDescription(currentWorkflow.description || "");
setIsActive(currentWorkflow.isActive);
}
}, [currentWorkflow]);
const handleSave = async () => {
if (!currentWorkflow) return;
// Local state'teki name, description, isActive değerlerini saveWorkflow'a gönder
const { nodes, edges } = useWorkflowStore.getState();
console.log("💾 handleSave - Mevcut nodes:", nodes.length, "edges:", edges.length);
console.log("💾 handleSave - Name:", name, "Description:", description, "IsActive:", isActive);
// Sonra API'ye kaydet (nodes, edges, name, description, isActive dahil)
const success = await saveWorkflow({
name,
description,
isActive,
});
if (success) {
alert("Workflow kaydedildi!");
} else {
const { error } = useWorkflowStore.getState();
alert(`Workflow kaydedilirken bir hata oluştu: ${error || "Bilinmeyen hata"}`);
}
};
const handleDelete = async () => {
if (!currentWorkflow) return;
if (confirm("Bu workflow'u silmek istediğinize emin misiniz?")) {
const success = await deleteWorkflow(currentWorkflow.id);
if (success) {
router.push("/");
} else {
alert("Workflow silinirken bir hata oluştu!");
}
}
};
const handleToggleActive = async () => {
if (!currentWorkflow) return;
const newActiveState = !isActive;
setIsActive(newActiveState);
const success = await updateWorkflow(currentWorkflow.id, {
isActive: newActiveState,
});
if (!success) {
setIsActive(!newActiveState); // Rollback
alert("Durum güncellenirken bir hata oluştu!");
}
};
const handleRun = async () => {
if (!currentWorkflow) return;
setIsRunning(true);
clearRunLogs();
const { nodes, addRunLog } = useWorkflowStore.getState();
// Simüle edilmiş run - gerçek uygulamada API'ye istek atılacak
for (const node of nodes) {
const startTime = new Date().toISOString();
addRunLog({
nodeId: node.id,
nodeName: node.data.label || node.data.type,
status: "running",
startTime,
});
// Simüle edilmiş işlem süresi
await new Promise((resolve) => setTimeout(resolve, 1000));
const endTime = new Date().toISOString();
const success = Math.random() > 0.2; // %80 başarı oranı
addRunLog({
nodeId: node.id,
nodeName: node.data.label || node.data.type,
status: success ? "success" : "error",
startTime,
endTime,
payload: { input: "test data", output: "processed data" },
error: success ? undefined : "Simüle edilmiş hata",
});
}
setIsRunning(false);
};
if (!currentWorkflow) {
return null;
}
return (
<div className="h-48 bg-dark-900 border-b border-dark-800 p-4 flex flex-col">
<div className="flex items-center justify-between mb-4">
<div className="flex items-center gap-3">
<Button
variant="ghost"
size="sm"
onClick={() => router.push("/")}
className="gap-2"
>
<ArrowLeft className="w-4 h-4" />
Geri
</Button>
<div>
<Input
value={name}
onChange={(e) => setName(e.target.value)}
placeholder="Workflow adı"
className="text-lg font-semibold border-0 bg-transparent focus:ring-0 p-0 h-auto"
/>
</div>
<Badge variant={isActive ? "success" : "default"}>
{isActive ? "Aktif" : "Pasif"}
</Badge>
</div>
<div className="flex items-center gap-2">
<Button
variant="ghost"
size="sm"
onClick={handleToggleActive}
disabled={isLoading}
className="gap-2"
>
<Power className="w-4 h-4" />
{isActive ? "Pasifleştir" : "Aktifleştir"}
</Button>
<Button
variant="danger"
size="sm"
onClick={handleDelete}
disabled={isLoading}
className="gap-2"
>
<Trash2 className="w-4 h-4" />
Sil
</Button>
<Button
variant="secondary"
size="sm"
onClick={handleSave}
disabled={isLoading}
className="gap-2"
>
<Save className="w-4 h-4" />
{isLoading ? "Kaydediliyor..." : "Kaydet"}
</Button>
<Button
size="sm"
onClick={handleRun}
disabled={isLoading}
className="gap-2"
>
<Play className="w-4 h-4" />
Çalıştır
</Button>
</div>
</div>
<div>
<Textarea
value={description}
onChange={(e) => setDescription(e.target.value)}
placeholder="Workflow açıklaması..."
rows={2}
className="bg-dark-800"
/>
</div>
</div>
);
}