async function loadCommentsForTask(taskId) { const rows=await apiGet(`/api/comments/${taskId}`); if(!rows) return; commentsCache[taskId]=rows; if(typeof commentCounts==='object') commentCounts[taskId]=rows.length; if(currentModalIdx!==null&&String(allData[currentModalIdx].task.id)===taskId){ const dbody=document.getElementById('detail-body'); if(dbody&¤tTab==='comments') dbody.innerHTML=renderCommentsHtml(taskId,rows); // Update tab label const tab=document.getElementById('dtab-comments'); if(tab) tab.textContent=`Наши комментарии${rows.length?` (${rows.length})`:''}`; } } function renderCommentsTab(){ if(currentModalIdx===null) return; const taskId=String(allData[currentModalIdx].task.id); const comments=commentsCache[taskId]||[]; const dbody=document.getElementById('detail-body'); if(dbody) dbody.innerHTML=renderCommentsHtml(taskId,comments); } function startEditComment(id, text) { const ea=document.getElementById(`cmt-edit-${id}`); const ta=document.getElementById(`cmt-edit-ta-${id}`); const td=document.getElementById(`cmt-text-${id}`); if(!ea||!ta) return; ta.value=text.replace(/\\n/g,'\n'); ea.style.display='flex';td.style.display='none';ta.focus(); } function cancelEditComment(id) { const ea=document.getElementById(`cmt-edit-${id}`); const td=document.getElementById(`cmt-text-${id}`); if(ea) ea.style.display='none'; if(td) td.style.display=''; } async function saveEditComment(id, taskId) { const ta=document.getElementById(`cmt-edit-ta-${id}`); const text=ta?.value?.trim(); if(!text) return; const r=await apiPost(`/api/comments/${id}`,{text},'PUT'); if(r?.id){ commentsCache[taskId]=(commentsCache[taskId]||[]).map(c=>c.id===id?r:c); renderCommentsTab(); } else showToast('❌ '+(r?.error||'Ошибка'),'warn'); } async function deleteComment(id, taskId) { if(!confirm('Удалить комментарий?')) return; const r=await apiDelete(`/api/comments/${id}`); if(r?.ok){ commentsCache[taskId]=(commentsCache[taskId]||[]).filter(c=>c.id!==id); if(typeof commentCounts==='object') commentCounts[taskId]=(commentsCache[taskId]||[]).length; renderCommentsTab(); renderTable(); } else showToast('❌ '+(r?.error||'Ошибка'),'warn'); } // @autocomplete function onCommentInput(ta) { const val=ta.value,pos=ta.selectionStart; const before=val.slice(0,pos); const match=before.match(/@([\w\u0400-\u04ff]*)$/); if(match){ acState={active:true,start:before.length-match[0].length,query:match[1].toLowerCase()}; showAutocomplete(ta,acState.query); } else {acState.active=false;hideAutocomplete();} } function showAutocomplete(ta,query) { const popup=document.getElementById('autocomplete-popup'); const matches=knownUsers.filter(u=>u.startsWith(query)&&u!==currentUser.username.toLowerCase()); if(!matches.length){hideAutocomplete();return;} popup.innerHTML=matches.slice(0,6).map(u=>`
${esc(u)}
`).join(''); popup.style.display='block'; } function hideAutocomplete(){const p=document.getElementById('autocomplete-popup');if(p)p.style.display='none';acState.active=false;} function handleAutocompleteKey(e){ if(!acState.active) return; const popup=document.getElementById('autocomplete-popup'); if(!popup||popup.style.display==='none') return; const items=popup.querySelectorAll('.autocomplete-item'); let sel=[...items].findIndex(i=>i.classList.contains('selected')); if(e.key==='ArrowDown'){e.preventDefault();if(sel=0)items[sel].classList.remove('selected');items[sel+1].classList.add('selected');}} else if(e.key==='ArrowUp'){e.preventDefault();if(sel>0){items[sel].classList.remove('selected');items[sel-1].classList.add('selected');}} else if(e.key==='Tab'||e.key==='Enter'){const ch=popup.querySelector('.selected')||items[0];if(ch){e.preventDefault();insertMention(ch.dataset.user);}} else if(e.key==='Escape') hideAutocomplete(); } function insertMention(username) { const ta=document.getElementById('composer-ta'); if(!ta) return; const val=ta.value; ta.value=val.slice(0,acState.start)+'@'+username+' '+val.slice(ta.selectionStart); ta.selectionStart=ta.selectionEnd=acState.start+username.length+2; hideAutocomplete();ta.focus(); }