60 lines
2.7 KiB
JavaScript
60 lines
2.7 KiB
JavaScript
function getNote(tid) {return notesCache[tid]?.text||'';}
|
||
function getNoteBy(tid) {return notesCache[tid]?.by||null;}
|
||
function getNoteAt(tid) {return notesCache[tid]?.at||null;}
|
||
|
||
// Status marks are mutually exclusive — only one at a time
|
||
const STATUS_MARKS = MARKS_CONFIG.map(m => m.key);
|
||
|
||
async function setMark(taskId, markType, e) {
|
||
e&&e.stopPropagation();
|
||
const tid = String(taskId);
|
||
if(!marksCache[tid]) marksCache[tid]={};
|
||
const now = new Date().toISOString();
|
||
const wasActive = marksCache[tid][markType]?.active;
|
||
|
||
// Clear all status marks first
|
||
STATUS_MARKS.forEach(m=>{
|
||
marksCache[tid][m]={...(marksCache[tid][m]||{}),active:false};
|
||
});
|
||
|
||
// Toggle: if was active → unset; else → set this one
|
||
if(!wasActive){
|
||
marksCache[tid][markType]={active:true,by:currentUser.username,at:now};
|
||
}
|
||
|
||
renderTable();
|
||
// Patch side panel mark buttons in-place without full re-render
|
||
if(currentModalIdx!==null){
|
||
const btns=document.querySelectorAll('.sp-marks .mark-btn[data-mark]');
|
||
if(btns.length){
|
||
const tid2=String(allData[currentModalIdx].task.id);
|
||
const states = Object.fromEntries(MARKS_CONFIG.map(m => [m.key, isMark(tid2, m.key)]));
|
||
btns.forEach(btn=>{
|
||
btn.classList.toggle('mbtn-active', !!states[btn.dataset.mark]);
|
||
});
|
||
// Also update sp-header badge
|
||
const badge=document.querySelector('.sp-header .sp-status-badge');
|
||
if(badge) badge.outerHTML=internalStatusBadge(tid2);
|
||
} else {
|
||
renderSidePanel(currentModalIdx);
|
||
}
|
||
}
|
||
|
||
// Один запрос — сервер сам сбрасывает остальные статусы и шлёт одно SSE
|
||
const newVal = !wasActive;
|
||
apiPost('/api/marks',{task_id:tid,mark_type:markType,value:newVal,clear_others:newVal});
|
||
}
|
||
|
||
function toggleMark(taskId, markType, e){ return setMark(taskId, markType, e); }
|
||
// Именованные алиасы — генерируются из MARKS_CONFIG, плюс ручные для совместимости
|
||
MARKS_CONFIG.forEach(m => {
|
||
const name = 'toggle' + m.key.replace(/_([a-z])/g, (_, c) => c.toUpperCase()).replace(/^(.)/, c => c.toUpperCase());
|
||
window[name] = (id, e) => setMark(id, m.key, e);
|
||
});
|
||
// Явные алиасы для обратной совместимости с inline-атрибутами HTML
|
||
function toggleResolved(id,e) { return setMark(id,'resolved',e); }
|
||
function toggleNeedsReply(id,e) { return setMark(id,'needs_reply',e); }
|
||
function toggleWaitClient(id,e) { return setMark(id,'wait_client',e); }
|
||
function toggleVyezdnye(id,e) { return setMark(id,'vyezdnye',e); }
|
||
function toggleOborudovanie(id,e) { return setMark(id,'oborudovanie',e); }
|
||
function toggleHidden(id,e) { return setMark(id,'hidden',e); }
|