Изменить срок

This commit is contained in:
2026-02-25 10:26:45 +05:00
parent fd928b6e3a
commit 6820550cbd
4 changed files with 283 additions and 607 deletions

View File

@@ -212,7 +212,11 @@ ${currentUser && currentUser.role === 'tasks' && canEdit || currentUser.role ===
${currentUser && currentUser.login === 'kalugin.o' ? `<button class="rework-btn" onclick="openReworkModal(${task.id})" title="Вернуть на доработку">🔄</button>` : ''}
<!-- Кнопка переделки документа для исполнителей -->
${task.task_type === 'document' && userRole === 'Исполнитель' ? `<button class="rework-btn" onclick="openReworkModal(${task.id})" title="Переделать документ">🔄Переделать</button>` : ''}
${currentUser && currentUser.login === 'minicrm' ? `<button class="close-btn" onclick="closeTask(${task.id})" title="Закрыть задачу">🔒</button>` : ''}
${!isDeleted && !isClosed && task.task_type !== 'regular' && task.assignments && task.assignments.some(a => parseInt(a.user_id) === currentUser.id) ?
`<button class="change-deadline-btn" onclick="openChangeDeadlineModal(${task.id})" title="Изменить срок">📅</button>` : ''}
${currentUser && currentUser.login === 'minicrm' ? `<button class="close-btn" onclick="closeTask(${task.id})" title="Закрыть задачу">🔒</button>` : ''}
${canEdit ? `<button class="delete-btn" onclick="deleteTask(${task.id})" title="Удалить">🗑️</button>` : ''}
` : ''}
${isClosed && canEdit ? `
@@ -1927,4 +1931,173 @@ function renderGroupedFiles(task) {
</div>
</div>
`).join('');
}
}
// ++++++++++++++++++++++++++++++ кнопки изменения срока задачи для исполнителей ++++++++++++++++++++++++++++++
// Функция для открытия модального окна изменения срока задачи
function openChangeDeadlineModal(taskId) {
const task = tasks.find(t => t.id === taskId);
if (!task) {
alert('Задача не найдена');
return;
}
// Проверяем, что задача не обычная (regular)
if (task.task_type === 'regular') {
alert('Для обычных задач изменение срока недоступно');
return;
}
// Проверяем, является ли пользователь исполнителем
const isExecutor = task.assignments && task.assignments.some(a =>
parseInt(a.user_id) === currentUser.id
);
if (!isExecutor && currentUser.role !== 'admin') {
alert('Только исполнители могут изменять срок задачи');
return;
}
const modalHtml = `
<div class="modal" id="change-deadline-modal">
<div class="modal-content" style="max-width: 500px;">
<div class="modal-header">
<h3>📅 Изменение срока задачи</h3>
<span class="close" onclick="closeChangeDeadlineModal()">&times;</span>
</div>
<div class="modal-body">
<p><strong>Задача:</strong> ${escapeHtml(task.title)}</p>
<p><strong>Тип:</strong> ${getTaskTypeDisplayName(task.task_type)}</p>
<p><strong>Текущий срок:</strong> ${formatDateTime(task.due_date)}</p>
<div class="form-group">
<label for="new-deadline-date"><strong>Новая дата выполнения:</strong></label>
<input type="date"
id="new-deadline-date"
class="form-control"
value="${new Date().toISOString().split('T')[0]}"
min="${new Date().toISOString().split('T')[0]}">
</div>
<div class="form-group">
<label for="deadline-change-comment"><strong>Комментарий к изменению срока:</strong></label>
<textarea id="deadline-change-comment"
class="form-control"
rows="4"
placeholder="Укажите причину изменения срока..."
required></textarea>
</div>
<div class="modal-footer">
<button type="button" class="nav-btn admin" onclick="closeChangeDeadlineModal()">Отмена</button>
<button type="button" class="btn-primary" onclick="submitDeadlineChange(${taskId})">✅ Изменить срок</button>
</div>
</div>
</div>
</div>
`;
const modalContainer = document.createElement('div');
modalContainer.innerHTML = modalHtml;
document.body.appendChild(modalContainer);
setTimeout(() => {
document.getElementById('change-deadline-modal').style.display = 'block';
document.getElementById('deadline-change-comment').focus();
}, 10);
}
// Функция закрытия модального окна
function closeChangeDeadlineModal() {
const modal = document.getElementById('change-deadline-modal');
if (modal) {
modal.style.display = 'none';
setTimeout(() => {
modal.parentElement.remove();
}, 300);
}
}
// Функция отправки изменения срока
async function submitDeadlineChange(taskId) {
const newDate = document.getElementById('new-deadline-date').value;
const comment = document.getElementById('deadline-change-comment').value.trim();
if (!newDate) {
alert('Пожалуйста, выберите новую дату');
return;
}
if (!comment) {
alert('Пожалуйста, укажите комментарий к изменению срока');
document.getElementById('deadline-change-comment').style.border = '2px solid red';
document.getElementById('deadline-change-comment').focus();
return;
}
// Формируем дату с временем 19:01 по местному времени
const deadlineDateTime = `${newDate}T19:01:00`;
const submitBtn = document.querySelector('#change-deadline-modal .btn-primary');
if (submitBtn) {
submitBtn.disabled = true;
submitBtn.innerHTML = '⏳ Сохранение...';
}
try {
// Получаем текущие данные задачи
const task = tasks.find(t => t.id === taskId);
// Обновляем задачу с новой датой
const response = await fetch(`/api/tasks/${taskId}`, {
method: 'PUT',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
title: task.title,
description: task.description,
dueDate: deadlineDateTime,
taskType: task.task_type
})
});
if (!response.ok) {
const error = await response.json();
throw new Error(error.error || 'Ошибка изменения срока');
}
// Добавляем комментарий в лог активности через отдельный эндпоинт
// (если есть API для комментариев)
try {
await fetch(`/api/tasks/${taskId}/comment`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
comment: `📅 Изменение срока: ${comment}`,
type: 'deadline_change'
})
});
} catch (commentError) {
console.warn('Не удалось сохранить комментарий:', commentError);
}
alert('✅ Срок задачи успешно изменен');
closeChangeDeadlineModal();
// Перезагружаем задачи
if (typeof loadTasks === 'function') {
loadTasks();
} else {
location.reload();
}
} catch (error) {
console.error('❌ Ошибка:', error);
alert(`❌ Ошибка: ${error.message}`);
if (submitBtn) {
submitBtn.disabled = false;
submitBtn.innerHTML = '✅ Изменить срок';
}
}
}
// ++++++++++++++++++++++++++++++ кнопки изменения срока задачи для исполнителей ++++++++++++++++++++++++++++++