Create subtask button + parent_id in CreateTaskModal

- '+ Подзадача' button in TaskModal subtasks section
- CreateTaskModal accepts parentId/parentKey props
- Title shows 'Подзадача для TE-1' when creating subtask
- parent_id sent to API on creation
- Optimistic update: new subtask appended to parent's subtasks list
This commit is contained in:
Markov 2026-02-28 00:14:52 +01:00
parent 4770fc62d7
commit f28909524c
2 changed files with 34 additions and 6 deletions

View File

@ -13,11 +13,13 @@ const PRIORITIES = [
interface Props {
projectId: string;
initialStatus: string;
parentId?: string;
parentKey?: string;
onClose: () => void;
onCreated: (task: Task) => void;
}
export default function CreateTaskModal({ projectId, initialStatus, onClose, onCreated }: Props) {
export default function CreateTaskModal({ projectId, initialStatus, parentId, parentKey, onClose, onCreated }: Props) {
const [title, setTitle] = useState("");
const [description, setDescription] = useState("");
const [priority, setPriority] = useState("medium");
@ -34,6 +36,7 @@ export default function CreateTaskModal({ projectId, initialStatus, onClose, onC
description: description.trim() || undefined,
status: initialStatus,
priority,
parent_id: parentId,
});
onCreated(task);
onClose();
@ -50,7 +53,9 @@ export default function CreateTaskModal({ projectId, initialStatus, onClose, onC
className="bg-[var(--card)] border border-[var(--border)] rounded-xl w-full max-w-md p-6"
onClick={(e) => e.stopPropagation()}
>
<h3 className="text-lg font-bold mb-4">Новая задача</h3>
<h3 className="text-lg font-bold mb-4">
{parentKey ? `Подзадача для ${parentKey}` : "Новая задача"}
</h3>
<div className="space-y-4">
<div>

View File

@ -1,6 +1,7 @@
import { useEffect, useState } from "react";
import type { Task, Member, Step, Message, TaskLink } from "@/lib/api";
import CreateTaskModal from "@/components/CreateTaskModal";
import {
updateTask, deleteTask, getMembers,
getSteps, createStep, updateStep, deleteStep as _deleteStepApi,
@ -55,6 +56,7 @@ export default function TaskModal({ task, projectId: _projectId, projectSlug: _p
const [_saving, setSaving] = useState(false);
const [editingDesc, setEditingDesc] = useState(false);
const [editingTitle, setEditingTitle] = useState(false);
const [showCreateSubtask, setShowCreateSubtask] = useState(false);
const [confirmDelete, setConfirmDelete] = useState(false);
const [newStep, setNewStep] = useState("");
const [newComment, setNewComment] = useState("");
@ -252,9 +254,15 @@ export default function TaskModal({ task, projectId: _projectId, projectSlug: _p
</div>
{/* Subtasks */}
{task.subtasks && task.subtasks.length > 0 && (
<div>
<div className="text-sm text-[var(--muted)] mb-2">Подзадачи ({task.subtasks.length})</div>
<div className="text-sm text-[var(--muted)] mb-2 flex items-center justify-between">
<span>Подзадачи{task.subtasks?.length ? ` (${task.subtasks.length})` : ""}</span>
<button
onClick={() => setShowCreateSubtask(true)}
className="text-xs text-[var(--accent)] hover:underline"
>+ Подзадача</button>
</div>
{task.subtasks && task.subtasks.length > 0 && (
<div className="space-y-1">
{task.subtasks.map((sub) => (
<div key={sub.id} className="flex items-center justify-between p-1.5 bg-[var(--bg)] border border-[var(--border)] rounded text-xs">
@ -276,7 +284,22 @@ export default function TaskModal({ task, projectId: _projectId, projectSlug: _p
</div>
))}
</div>
)}
</div>
{showCreateSubtask && (
<CreateTaskModal
projectId={task.project_id}
initialStatus="todo"
parentId={task.id}
parentKey={task.key}
onClose={() => setShowCreateSubtask(false)}
onCreated={(newTask) => {
// Refresh parent task to show new subtask
onUpdated({ ...task, subtasks: [...(task.subtasks || []), { id: newTask.id, key: newTask.key, title: newTask.title, status: newTask.status, assignee: newTask.assignee }] });
setShowCreateSubtask(false);
}}
/>
)}
{/* Dependencies */}