intra_monitor/public/js/comments.js
2026-03-18 14:19:29 +03:00

94 lines
4.3 KiB
JavaScript

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&&currentTab==='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=>`<div class="autocomplete-item" data-user="${esc(u)}" onclick="insertMention('${esc(u)}')">${esc(u)}</div>`).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<items.length-1){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();
}