From ef839683aed1f501e0de507e2ca72ccdc7b29666 Mon Sep 17 00:00:00 2001 From: soryu Date: Wed, 21 Jan 2026 16:18:11 +0000 Subject: feat(frontend): Add BranchTaskModal component Modal component for creating a branched task from an existing task. Features: - Pre-filled name with "Branch of {taskName}" - Required message textarea for initial task instruction - Cancel and Create Branch buttons with purple theme - Error message display on failure - Follows existing modal patterns (PhaseConfirmationModal) Co-Authored-By: Claude Opus 4.5 --- .../src/components/mesh/BranchTaskModal.tsx | 132 +++++++++++++++++++++ 1 file changed, 132 insertions(+) create mode 100644 makima/frontend/src/components/mesh/BranchTaskModal.tsx diff --git a/makima/frontend/src/components/mesh/BranchTaskModal.tsx b/makima/frontend/src/components/mesh/BranchTaskModal.tsx new file mode 100644 index 0000000..ade4c7d --- /dev/null +++ b/makima/frontend/src/components/mesh/BranchTaskModal.tsx @@ -0,0 +1,132 @@ +import { useState } from "react"; +import type { TaskWithSubtasks } from "../../lib/api"; + +interface BranchTaskModalProps { + task: TaskWithSubtasks; + onBranch: (taskId: string, message: string, name?: string) => Promise; + onClose: () => void; +} + +export function BranchTaskModal({ + task, + onBranch, + onClose, +}: BranchTaskModalProps) { + const [name, setName] = useState(`Branch of ${task.name}`); + const [message, setMessage] = useState(""); + const [submitting, setSubmitting] = useState(false); + const [error, setError] = useState(null); + + const handleSubmit = async () => { + if (!message.trim()) { + setError("Message is required"); + return; + } + + setSubmitting(true); + setError(null); + + try { + await onBranch(task.id, message.trim(), name.trim() || undefined); + onClose(); + } catch (err) { + setError(err instanceof Error ? err.message : "Failed to create branch"); + } finally { + setSubmitting(false); + } + }; + + return ( +
+
+ {/* Header */} +
+
+ * +

+ Branch Task +

+
+ +
+ + {/* Content */} +
+ {/* Source task info */} +
+

+ Branching From +

+

{task.name}

+

+ Status: {task.status} +

+
+ + {/* Name input */} +
+ + setName(e.target.value)} + placeholder="Enter branch task name..." + className="w-full px-3 py-2 bg-[#0d1b2d] border border-[#3f6fb3] text-[#dbe7ff] font-mono text-sm focus:outline-none focus:border-[#75aafc]" + /> +
+ + {/* Message input */} +
+ +