diff --git a/public/nav-task-actions.js b/public/nav-task-actions.js index 60370d4..1929efb 100644 --- a/public/nav-task-actions.js +++ b/public/nav-task-actions.js @@ -20,6 +20,32 @@ const canEdit = window.canUserEditTask ? window.canUserEditTask(task) : false; const actions = []; +// ==== ДОБАВЛЕННЫЙ БЛОК: кнопки для текущего исполнителя +if (currentUser && !isDeleted && !isClosed) { + const myAssignment = task.assignments?.find(a => parseInt(a.user_id) === currentUser.id); + if (myAssignment) { + // Кнопка "Приступить" (если статус 'assigned') + if (myAssignment.status === 'assigned') { + actions.push({ + label: '▶️ Приступить', + handler: () => window.updateStatus(taskId, currentUser.id, 'in_progress'), + primary: true + }); + } + // Кнопка "Выполнено" (если статус 'in_progress', 'overdue' или 'rework') + if (['in_progress', 'overdue', 'rework'].includes(myAssignment.status)) { + const isDocumentTask = task.task_type === 'document'; + const handler = isDocumentTask + ? () => window.openDocumentCompleteModal(taskId, currentUser.id) + : () => window.updateStatus(taskId, currentUser.id, 'completed'); + actions.push({ + label: '✅ Выполнено', + handler: handler, + primary: true + }); + } + } +} // Действия для активных (не удалённых, не закрытых) задач if (!isDeleted && !isClosed) { if (typeof openTaskChat === 'function') { @@ -165,6 +191,9 @@ log('nav-task-actions openChangeDeadlineModal yes'); const actions = buildActionsForTask(task); if (actions.length === 0) return; + // primary + const primaryActions = actions.filter(a => a.primary); + const otherActions = actions.filter(a => !a.primary); // Создаём затемнение const overlay = document.createElement('div'); overlay.id = 'task-action-modal'; @@ -204,6 +233,8 @@ log('nav-task-actions openChangeDeadlineModal yes'); title.style.margin = '0'; title.style.fontSize = '18px'; title.style.color = '#333'; + title.style.flex = '1'; + title.style.textAlign = 'center'; title.textContent = `Действия для задачи #${taskId}`; const closeBtn = document.createElement('span'); @@ -221,47 +252,73 @@ log('nav-task-actions openChangeDeadlineModal yes'); header.appendChild(closeBtn); modal.appendChild(header); +// === НОВЫЙ БЛОК: primary actions === +if (primaryActions.length > 0) { + const primaryContainer = document.createElement('div'); + primaryContainer.style.marginBottom = '20px'; + primaryActions.forEach(a => { + const btn = document.createElement('button'); + btn.textContent = a.label; + btn.style.cssText = ` + width: 100%; + padding: 14px; + background-color: #27ae60; + color: white; + border: none; + border-radius: 8px; + font-size: 16px; + font-weight: 500; + cursor: pointer; + transition: background-color 0.2s; + margin-bottom: 10px; + `; + btn.onmouseover = () => { btn.style.backgroundColor = '#229954'; }; + btn.onmouseout = () => { btn.style.backgroundColor = '#27ae60'; }; + btn.onclick = (event) => { + event.stopPropagation(); + a.handler(); + removeModal(); + }; + primaryContainer.appendChild(btn); + }); + modal.appendChild(primaryContainer); +} // Сетка кнопок (flex-wrap с 3 колонками) - const grid = document.createElement('div'); - grid.style.display = 'flex'; - grid.style.flexWrap = 'wrap'; - grid.style.gap = '10px'; - grid.style.justifyContent = 'center'; - - actions.forEach(a => { - const btn = document.createElement('button'); - btn.textContent = a.label; - btn.style.flex = '0 0 calc(33.333% - 10px)'; - btn.style.minWidth = '120px'; - btn.style.padding = '12px 8px'; - btn.style.border = 'none'; - btn.style.borderRadius = '8px'; - btn.style.backgroundColor = '#3498db'; - btn.style.color = 'white'; - btn.style.fontSize = '14px'; - btn.style.fontWeight = '500'; - btn.style.cursor = 'pointer'; - btn.style.transition = 'all 0.2s'; - btn.style.boxShadow = '0 2px 5px rgba(52,152,219,0.3)'; - - btn.onmouseover = () => { - btn.style.transform = 'translateY(-2px)'; - btn.style.boxShadow = '0 4px 10px rgba(52,152,219,0.4)'; - }; - btn.onmouseout = () => { - btn.style.transform = 'translateY(0)'; - btn.style.boxShadow = '0 2px 5px rgba(52,152,219,0.3)'; - }; - btn.onclick = (event) => { - event.stopPropagation(); - a.handler(); - removeModal(); - }; - - grid.appendChild(btn); - }); - - modal.appendChild(grid); +if (otherActions.length > 0) { + const grid = document.createElement('div'); + grid.style.cssText = ` + display: flex; + flex-wrap: wrap; + gap: 10px; + justify-content: center; + `; + otherActions.forEach(a => { + const btn = document.createElement('button'); + btn.textContent = a.label; + btn.style.cssText = ` + flex: 0 0 calc(33.333% - 10px); + min-width: 120px; + padding: 12px 8px; + border: none; + border-radius: 8px; + background-color: #3498db; + color: white; + font-size: 14px; + font-weight: 500; + cursor: pointer; + transition: background-color 0.2s; + `; + btn.onmouseover = () => { btn.style.backgroundColor = '#2980b9'; }; + btn.onmouseout = () => { btn.style.backgroundColor = '#3498db'; }; + btn.onclick = (event) => { + event.stopPropagation(); + a.handler(); + removeModal(); + }; + grid.appendChild(btn); + }); + modal.appendChild(grid); +} overlay.appendChild(modal); document.body.appendChild(overlay); diff --git a/public/ui.js b/public/ui.js index 6084005..0a3c00e 100644 --- a/public/ui.js +++ b/public/ui.js @@ -168,14 +168,14 @@ if (statusFilter !== 'completed') {