Files
minicrm/public/main.js

399 lines
15 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// 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');
}
// Функции для работы с модальными окнами (добавьте если их нет)
function closeEditModal() {
document.getElementById('edit-task-modal').style.display = 'none';
document.getElementById('edit-file-list').innerHTML = '';
document.getElementById('edit-user-search').value = '';
editSelectedUsers = [];
currentEditTaskFiles = [];
filterEditUsers();
}
function closeCopyModal() {
document.getElementById('copy-task-modal').style.display = 'none';
document.getElementById('copy-user-search').value = '';
copySelectedUsers = [];
filterCopyUsers();
}
function closeEditAssignmentModal() {
document.getElementById('edit-assignment-modal').style.display = 'none';
}
function closeReworkModal() {
document.getElementById('rework-task-modal').style.display = 'none';
document.getElementById('rework-comment').value = '';
}