// main.js - Главный файл инициализации let currentTaskView = 'all'; // 'all', 'my_assigned', 'assigned_to_me' let allTasksCache = []; // Кэш всех задач document.addEventListener('DOMContentLoaded', function() { checkAuth(); setupEventListeners(); // Инициализация выбора времени initializeTimeSelectors(); // Инициализация фильтра const taskViewFilter = document.getElementById('task-view-filter'); if (taskViewFilter) { taskViewFilter.value = currentTaskView; } // По умолчанию показываем секцию задач showSection('tasks'); }); function setupEventListeners() { // Форма входа document.getElementById('login-form').addEventListener('submit', login); // Формы задач document.getElementById('create-task-form').addEventListener('submit', createTask); document.getElementById('edit-task-form').addEventListener('submit', updateTask); document.getElementById('copy-task-form').addEventListener('submit', copyTask); document.getElementById('edit-assignment-form').addEventListener('submit', updateAssignment); document.getElementById('rework-task-form').addEventListener('submit', sendForRework); // Файлы document.getElementById('files').addEventListener('change', updateFileList); document.getElementById('edit-files').addEventListener('change', updateEditFileList); // Настройки уведомлений const notificationForm = document.getElementById('notification-settings-form'); if (notificationForm) { notificationForm.addEventListener('submit', saveNotificationSettings); } // Инициализация загрузки файлов initializeFileUploads(); } // Функция для изменения вида задач function changeTaskView() { const select = document.getElementById('task-view-filter'); currentTaskView = select.value; loadTasks(); } // Переопределяем функцию loadTasks для фильтрации (function() { // Сохраняем оригинальную функцию loadTasks const originalLoadTasks = window.loadTasks; // Создаем новую функцию window.loadTasks = async function() { // Вызываем оригинальную функцию if (typeof originalLoadTasks === 'function') { await originalLoadTasks(); } // Кэшируем все задачи if (window.tasks && Array.isArray(window.tasks)) { allTasksCache = [...window.tasks]; // Фильтруем задачи в зависимости от выбранного вида if (currentTaskView !== 'all' && currentUser) { let filteredTasks = []; if (currentTaskView === 'my_assigned') { // Показываем задачи, которые я назначил (я - создатель) filteredTasks = window.tasks.filter(task => { return parseInt(task.created_by) === currentUser.id; }); } else if (currentTaskView === 'assigned_to_me') { // Показываем задачи, назначенные мне (я - исполнитель) filteredTasks = window.tasks.filter(task => { // Проверяем, назначена ли задача текущему пользователю if (task.assignments && Array.isArray(task.assignments)) { return task.assignments.some(assignment => parseInt(assignment.user_id) === currentUser.id ); } return false; }); } // Обновляем глобальный массив задач window.tasks = filteredTasks; // Перерисовываем задачи if (window.renderTasks && typeof window.renderTasks === 'function') { window.renderTasks(); } } } }; })(); // Обновленная функция для создания задачи async function createTask(event) { event.preventDefault(); if (!currentUser) { alert('Требуется аутентификация'); return; } const title = document.getElementById('title').value; const description = document.getElementById('description').value; const taskType = document.getElementById('task-type').value; // Получаем полную дату и время из отдельных полей const fullDateTime = getFullDateTime('due-date', 'due-time'); if (!title || !fullDateTime) { alert('Название задачи и дата выполнения обязательны'); return; } if (selectedUsers.length === 0) { alert('Выберите хотя бы одного исполнителя'); return; } const formData = new FormData(); formData.append('title', title); formData.append('description', description); formData.append('taskType', taskType); formData.append('dueDate', fullDateTime); selectedUsers.forEach(userId => { formData.append('assignedUsers', userId); }); const files = document.getElementById('files').files; for (let i = 0; i < files.length; i++) { formData.append('files', files[i]); } // Проверка прав для типа "regular" const userGroups = currentUser?.groups || []; const isAdmin = currentUser?.role === 'admin'; const hasTasksGroup = currentUser?.role === 'tasks'; const hasSecretaryGroup = currentUser?.role === 'secretary'; if (taskType === 'regular' && !(isAdmin || hasTasksGroup || hasSecretaryGroup)) { alert('У вас нет прав для создания обычных задач. Выберите другой тип задачи.'); return; } try { const response = await fetch('/api/tasks', { method: 'POST', body: formData }); if (response.ok) { alert('Задача успешно создана!'); // Сброс формы document.getElementById('create-task-form').reset(); document.getElementById('file-list').innerHTML = ''; document.getElementById('user-search').value = ''; selectedUsers = []; // Сбрасываем дату и время const tomorrow = new Date(); tomorrow.setDate(tomorrow.getDate() + 1); document.getElementById('due-date').value = tomorrow.toISOString().split('T')[0]; document.getElementById('due-time').value = '12:00'; // Сбрасываем активные кнопки const timeButtons = document.querySelectorAll('.time-btn'); timeButtons.forEach(btn => btn.classList.remove('active')); if (timeButtons.length > 0) { timeButtons[0].classList.add('active'); } // Обновляем отображение кнопок updateDateTimeDisplay(); // Обновляем список пользователей renderUsersChecklist(); // Загружаем задачи и логи loadTasks(); loadActivityLogs(); // Показываем секцию задач showSection('tasks'); } else { const error = await response.json(); alert(error.error || 'Ошибка создания задачи'); } } catch (error) { console.error('Ошибка:', error); alert('Ошибка создания задачи'); } } // Обновленная функция открытия модального окна редактирования async function openEditModal(taskId) { try { const response = await fetch(`/api/tasks/${taskId}`); if (!response.ok) { if (response.status === 404) { alert('Задача не найдена или у вас нет прав доступа'); } throw new Error('Ошибка загрузки задачи'); } const task = await response.json(); if (!canUserEditTask(task)) { alert('У вас нет прав для редактирования этой задачи'); return; } document.getElementById('edit-task-id').value = task.id; document.getElementById('edit-title').value = task.title; document.getElementById('edit-description').value = task.description || ''; // Устанавливаем дату и время с помощью новой функции setDateTimeForEdit(task.due_date); // Устанавливаем выбранных пользователей editSelectedUsers = task.assignments ? task.assignments.map(a => a.user_id) : []; renderEditUsersChecklist(users); // Показываем существующие файлы currentEditTaskFiles = task.files || []; updateEditFileList(); document.getElementById('edit-task-modal').style.display = 'block'; } catch (error) { console.error('Ошибка:', error); alert('Ошибка загрузки задачи'); } } // Обновленная функция обновления задачи async function updateTask(event) { event.preventDefault(); const taskId = document.getElementById('edit-task-id').value; const title = document.getElementById('edit-title').value; const description = document.getElementById('edit-description').value; // Получаем полную дату и время из отдельных полей const fullDateTime = getFullDateTime('edit-due-date', 'edit-due-time'); if (!fullDateTime) { alert('Дата и время выполнения обязательны'); return; } // Используем editSelectedUsers const assignedUserIds = editSelectedUsers; const formData = new FormData(); formData.append('title', title); formData.append('description', description); formData.append('assignedUsers', JSON.stringify(assignedUserIds)); formData.append('dueDate', fullDateTime); const files = document.getElementById('edit-files').files; for (let i = 0; i < files.length; i++) { formData.append('files', files[i]); } try { const response = await fetch(`/api/tasks/${taskId}`, { method: 'PUT', body: formData }); if (response.ok) { alert('Задача успешно обновлена!'); closeEditModal(); loadTasks(); loadActivityLogs(); } else { const error = await response.json(); alert(error.error || 'Ошибка обновления задачи'); } } catch (error) { console.error('Ошибка:', error); alert('Ошибка обновления задачи'); } } // Обновленная функция создания копии задачи async function copyTask(event) { event.preventDefault(); const taskId = document.getElementById('copy-task-id').value; // Получаем полную дату и время из отдельных полей const fullDateTime = getFullDateTime('copy-due-date', 'copy-due-time'); if (!fullDateTime) { alert('Дата и время выполнения обязательны для копии задачи'); return; } // Используем copySelectedUsers const assignedUserIds = copySelectedUsers; if (assignedUserIds.length === 0) { alert('Выберите хотя бы одного исполнителя для копии задачи'); return; } try { const response = await fetch(`/api/tasks/${taskId}/copy`, { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ assignedUsers: assignedUserIds, dueDate: fullDateTime }) }); if (response.ok) { alert('Копия задачи успешно создана!'); closeCopyModal(); loadTasks(); loadActivityLogs(); } else { const error = await response.json(); alert(error.error || 'Ошибка создания копии задачи'); } } catch (error) { console.error('Ошибка:', error); alert('Ошибка создания копии задачи'); } } // Функция для отображения секции function showSection(sectionName) { document.querySelectorAll('.section').forEach(section => { section.classList.remove('active'); }); document.getElementById(sectionName + '-section').classList.add('active'); if (sectionName === 'tasks') { loadTasks(); } else if (sectionName === 'logs') { loadActivityLogs(); } else if (sectionName === 'kanban') { loadKanbanTasks(); } // Загрузка профиля при переходе в личный кабинет if (sectionName === 'profile') { loadUserProfile(); loadNotificationSettings(); } } // Функция для отображения Канбан доски function showKanbanSection() { showSection('kanban'); }