This commit is contained in:
2025-12-14 17:48:56 +05:00
parent b6e302bf57
commit d25ac311f3
4 changed files with 250 additions and 130 deletions

View File

@@ -3,6 +3,8 @@ let users = [];
let tasks = [];
let filteredUsers = [];
let expandedTasks = new Set();
let showingTasksWithoutDate = false;
document.addEventListener('DOMContentLoaded', function() {
checkAuth();
setupEventListeners();
@@ -57,6 +59,10 @@ function showMainInterface() {
loadTasks();
loadActivityLogs();
showSection('tasks');
showingTasksWithoutDate = false;
const btn = document.getElementById('tasks-no-date-btn');
if (btn) btn.classList.remove('active');
}
function setupEventListeners() {
@@ -187,6 +193,10 @@ function filterCopyUsers() {
async function loadTasks() {
try {
showingTasksWithoutDate = false;
const btn = document.getElementById('tasks-no-date-btn');
if (btn) btn.classList.remove('active');
const search = document.getElementById('search-tasks')?.value || '';
const statusFilter = document.getElementById('status-filter')?.value || 'active,in_progress,assigned,overdue,rework';
const creatorFilter = document.getElementById('creator-filter')?.value || '';
@@ -214,6 +224,32 @@ async function loadTasks() {
}
}
function showTasksWithoutDate() {
showingTasksWithoutDate = true;
const btn = document.getElementById('tasks-no-date-btn');
if (btn) btn.classList.add('active');
loadTasksWithoutDate();
}
async function loadTasksWithoutDate() {
try {
const response = await fetch('/api/tasks');
if (!response.ok) throw new Error('Ошибка загрузки задач');
const allTasks = await response.json();
tasks = allTasks.filter(task => {
const hasTaskDueDate = !task.due_date;
const hasAssignmentDueDates = task.assignments &&
task.assignments.every(assignment => !assignment.due_date);
return hasTaskDueDate && hasAssignmentDueDates;
});
renderTasks();
} catch (error) {
console.error('Ошибка загрузки задач без срока:', error);
}
}
async function loadActivityLogs() {
try {
const response = await fetch('/api/activity-logs');
@@ -296,7 +332,7 @@ function renderTasks() {
const timeLeftInfo = getTimeLeftInfo(task);
return `
<div class="task-card ${isDeleted ? 'deleted' : ''} ${isClosed ? 'closed' : ''}">
<div class="task-card ${isDeleted ? 'deleted' : ''} ${isClosed ? 'closed' : ''}" data-task-id="${task.id}">
<div class="task-header">
<div class="task-title" onclick="toggleTask(${task.id})" style="cursor: pointer; display: flex; justify-content: space-between; align-items: center;">
<div style="flex: 1;">
@@ -315,7 +351,7 @@ function renderTasks() {
</div>
</div>
<div class="task-content" style="display: ${isExpanded ? 'block' : 'none'};">
<div class="task-content ${isExpanded ? 'expanded' : ''}">
<div class="task-actions">
${!isDeleted && !isClosed ? `
${canEdit ? `<button class="edit-btn" onclick="openEditModal(${task.id})" title="Редактировать">✏️</button>` : ''}
@@ -346,12 +382,16 @@ function renderTasks() {
</div>
` : ''}
${task.start_date || task.due_date ? `
<div class="task-dates-files">
<div class="task-dates">
<div><strong>Создана:</strong> ${formatDateTime(task.start_date || task.created_at)}</div>
${task.due_date ? `<div><strong>Выполнить до:</strong> ${formatDateTime(task.due_date)}</div>` : ''}
<strong>Создана:</strong> ${formatDateTime(task.start_date || task.created_at)}
${task.due_date ? ` | <strong>Выполнить до:</strong> ${formatDateTime(task.due_date)}` : ''}
${showingTasksWithoutDate ? '<span class="no-date-badge">Без срока</span>' : ''}
</div>
` : ''}
<div class="file-list" id="files-${task.id}">
<strong>Файлы:</strong> <span class="files-placeholder">скрыто</span>
</div>
</div>
<div class="task-assignments">
<strong>Исполнители:</strong>
@@ -361,11 +401,6 @@ function renderTasks() {
}
</div>
<div class="file-list" id="files-${task.id}">
<strong>Файлы:</strong>
<div class="loading">Загрузка...</div>
</div>
<div class="task-meta">
<small>Создана: ${formatDateTime(task.created_at)} | Автор: ${task.creator_name}</small>
${task.deleted_at ? `<br><small>Удалена: ${formatDateTime(task.deleted_at)}</small>` : ''}
@@ -376,6 +411,7 @@ function renderTasks() {
`;
}).join('');
}
function toggleTask(taskId) {
if (expandedTasks.has(taskId)) {
expandedTasks.delete(taskId);
@@ -384,6 +420,7 @@ function toggleTask(taskId) {
}
renderTasks();
}
function getTimeLeftInfo(task) {
if (!task.due_date || task.closed_at) return null;
@@ -838,7 +875,7 @@ async function deleteTask(taskId) {
const error = await response.json();
alert(error.error || 'Ошибка удаления задачи');
}
} catch (error) {
} catch (error) {
console.error('Ошибка:', error);
alert('Ошибка удаления задачи');
}
@@ -1081,7 +1118,7 @@ async function loadTaskFiles(taskId) {
const container = document.getElementById(`files-${taskId}`);
if (container) {
if (files.length === 0) {
container.innerHTML = '<strong>Файлы:</strong> Нет файлов';
container.innerHTML = '<strong>Файлы:</strong> <span class="files-placeholder">скрыто</span>';
} else {
container.innerHTML = `
<strong>Файлы:</strong>