r
This commit is contained in:
@@ -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>
|
||||
|
||||
Reference in New Issue
Block a user