From 60cc538b28dadca53737ea7a9981fab5c42d18e4 Mon Sep 17 00:00:00 2001 From: Markov Date: Sat, 28 Feb 2026 00:26:53 +0100 Subject: [PATCH] Task search autocomplete for dependency linking - searchTasks API function (q= param) - Autocomplete dropdown: search by number or title - Shows task key + title, click to select - Replaces raw ID input --- src/components/TaskModal.tsx | 45 +++++++++++++++++++++++++++++++----- src/lib/api.ts | 4 ++++ 2 files changed, 43 insertions(+), 6 deletions(-) diff --git a/src/components/TaskModal.tsx b/src/components/TaskModal.tsx index 471ddd9..d9485f3 100644 --- a/src/components/TaskModal.tsx +++ b/src/components/TaskModal.tsx @@ -7,6 +7,7 @@ import { getSteps, createStep, updateStep, deleteStep as _deleteStepApi, getMessages, sendMessage, getTaskLinks, createTaskLink, deleteTaskLink, + searchTasks, } from "@/lib/api"; const STATUSES = [ @@ -51,6 +52,8 @@ export default function TaskModal({ task, projectId: _projectId, projectSlug: _p const [links, setLinks] = useState([]); const [showAddLink, setShowAddLink] = useState(false); const [linkTargetId, setLinkTargetId] = useState(""); + const [linkSearch, setLinkSearch] = useState(""); + const [linkSearchResults, setLinkSearchResults] = useState([]); const [linkType, setLinkType] = useState("depends_on"); const [comments, setComments] = useState([]); const [_saving, setSaving] = useState(false); @@ -338,18 +341,48 @@ export default function TaskModal({ task, projectId: _projectId, projectSlug: _p - setLinkTargetId(e.target.value)} - placeholder="ID задачи..." - className="flex-1 px-2 py-1 bg-[var(--bg)] border border-[var(--border)] rounded text-xs outline-none" - /> +
+ { + const v = e.target.value; + setLinkSearch(v); + if (v.length >= 1) { + const results = await searchTasks(task.project_id, v); + setLinkSearchResults(results.filter(t => t.id !== task.id)); + } else { + setLinkSearchResults([]); + } + }} + placeholder="Поиск по номеру или названию..." + className="w-full px-2 py-1 bg-[var(--bg)] border border-[var(--border)] rounded text-xs outline-none" + /> + {linkSearchResults.length > 0 && ( +
+ {linkSearchResults.map(t => ( + + ))} +
+ )} +