233 lines
8.0 KiB
JavaScript
233 lines
8.0 KiB
JavaScript
document.addEventListener('DOMContentLoaded', () => {
|
|
const toastEl = document.getElementById('appToast');
|
|
if (toastEl && window.bootstrap) {
|
|
const toast = new bootstrap.Toast(toastEl);
|
|
toast.show();
|
|
}
|
|
|
|
document.querySelectorAll('.needs-validation').forEach((form) => {
|
|
form.addEventListener('submit', (event) => {
|
|
if (!form.checkValidity()) {
|
|
event.preventDefault();
|
|
event.stopPropagation();
|
|
}
|
|
form.classList.add('was-validated');
|
|
});
|
|
});
|
|
|
|
const activeItem = document.querySelector('.task-item-active');
|
|
if (activeItem && window.innerWidth < 1200) {
|
|
activeItem.scrollIntoView({ behavior: 'smooth', block: 'nearest' });
|
|
}
|
|
|
|
const taskList = document.querySelector('.task-list');
|
|
const detailContent = document.getElementById('taskDetailContent');
|
|
|
|
if (!taskList || !detailContent) {
|
|
return;
|
|
}
|
|
|
|
const detailPriorityBadge = document.getElementById('detailPriorityBadge');
|
|
const detailStatusBadge = document.getElementById('detailStatusBadge');
|
|
const detailTitle = document.getElementById('detailTitle');
|
|
const detailDescription = document.getElementById('detailDescription');
|
|
const detailCreated = document.getElementById('detailCreated');
|
|
const detailUpdated = document.getElementById('detailUpdated');
|
|
const detailCompleted = document.getElementById('detailCompleted');
|
|
const detailEditLink = document.getElementById('detailEditLink');
|
|
const detailToggleTaskId = document.getElementById('detailToggleTaskId');
|
|
const detailDeleteTaskId = document.getElementById('detailDeleteTaskId');
|
|
const detailToggleIcon = document.getElementById('detailToggleIcon');
|
|
const detailToggleText = document.getElementById('detailToggleText');
|
|
const taskEditorForm = document.getElementById('taskEditorForm');
|
|
const taskFormAction = document.getElementById('taskFormAction');
|
|
const taskFormTaskId = document.getElementById('taskFormTaskId');
|
|
const taskFormSelectedTask = document.getElementById('taskFormSelectedTask');
|
|
const taskFormTitle = document.getElementById('taskFormTitle');
|
|
const taskFormEyebrow = document.getElementById('taskFormEyebrow');
|
|
const taskFormCancelLink = document.getElementById('taskFormCancelLink');
|
|
const taskTitleInput = document.getElementById('title');
|
|
const taskDescriptionInput = document.getElementById('description');
|
|
const taskPriorityInput = document.getElementById('priority');
|
|
const isEditingMode = taskEditorForm?.dataset.formMode === 'update';
|
|
|
|
const syncActiveState = (selectedItem) => {
|
|
document.querySelectorAll('.task-item').forEach((item) => {
|
|
const isActive = item === selectedItem;
|
|
item.classList.toggle('task-item-active', isActive);
|
|
item.setAttribute('aria-pressed', isActive ? 'true' : 'false');
|
|
});
|
|
};
|
|
|
|
const syncEditForm = (taskItem) => {
|
|
if (!isEditingMode || !taskItem) {
|
|
return;
|
|
}
|
|
|
|
if (taskFormAction) {
|
|
taskFormAction.value = 'update';
|
|
}
|
|
|
|
if (taskFormTaskId) {
|
|
taskFormTaskId.value = taskItem.dataset.taskId || '';
|
|
}
|
|
|
|
if (taskFormSelectedTask) {
|
|
taskFormSelectedTask.value = taskItem.dataset.taskId || '';
|
|
}
|
|
|
|
if (taskTitleInput) {
|
|
taskTitleInput.value = taskItem.dataset.taskTitle || '';
|
|
}
|
|
|
|
if (taskDescriptionInput) {
|
|
taskDescriptionInput.value = taskItem.dataset.taskDescriptionRaw || '';
|
|
}
|
|
|
|
if (taskPriorityInput) {
|
|
taskPriorityInput.value = taskItem.dataset.taskPriorityValue || 'medium';
|
|
}
|
|
|
|
if (taskFormTitle) {
|
|
taskFormTitle.textContent = 'Обновить задачу';
|
|
}
|
|
|
|
if (taskFormEyebrow) {
|
|
taskFormEyebrow.textContent = 'Редактирование';
|
|
}
|
|
|
|
if (taskFormCancelLink) {
|
|
const cancelUrl = new URL(taskItem.dataset.taskEditUrl || 'index.php', window.location.origin);
|
|
cancelUrl.searchParams.delete('edit');
|
|
taskFormCancelLink.href = `${cancelUrl.pathname}${cancelUrl.search}${cancelUrl.hash}`;
|
|
}
|
|
};
|
|
|
|
const updateHistory = (taskId) => {
|
|
const url = new URL(window.location.href);
|
|
url.searchParams.set('task', taskId);
|
|
|
|
if (isEditingMode) {
|
|
url.searchParams.set('edit', taskId);
|
|
} else {
|
|
url.searchParams.delete('edit');
|
|
}
|
|
|
|
history.replaceState({ taskId }, '', url);
|
|
};
|
|
|
|
const selectTask = (taskItem, shouldSyncHistory = true) => {
|
|
if (!taskItem) {
|
|
return;
|
|
}
|
|
|
|
syncActiveState(taskItem);
|
|
detailContent.dataset.selectedTaskId = taskItem.dataset.taskId || '';
|
|
|
|
if (detailPriorityBadge) {
|
|
detailPriorityBadge.className = `priority-badge ${taskItem.dataset.taskPriorityClass || ''}`.trim();
|
|
detailPriorityBadge.textContent = taskItem.dataset.taskPriorityLabel || '';
|
|
}
|
|
|
|
if (detailStatusBadge) {
|
|
detailStatusBadge.className = `status-badge ${taskItem.dataset.taskStatusClass || ''}`.trim();
|
|
detailStatusBadge.textContent = taskItem.dataset.taskStatusLabel || '';
|
|
}
|
|
|
|
if (detailTitle) {
|
|
detailTitle.textContent = taskItem.dataset.taskTitle || '';
|
|
}
|
|
|
|
if (detailDescription) {
|
|
detailDescription.textContent = taskItem.dataset.taskDescription || '';
|
|
}
|
|
|
|
if (detailCreated) {
|
|
detailCreated.textContent = taskItem.dataset.taskCreatedLabel || '';
|
|
}
|
|
|
|
if (detailUpdated) {
|
|
detailUpdated.textContent = taskItem.dataset.taskUpdatedLabel || '';
|
|
}
|
|
|
|
if (detailCompleted) {
|
|
detailCompleted.textContent = taskItem.dataset.taskCompletedLabel || '';
|
|
}
|
|
|
|
if (detailEditLink) {
|
|
detailEditLink.href = taskItem.dataset.taskEditUrl || 'index.php';
|
|
}
|
|
|
|
if (detailToggleTaskId) {
|
|
detailToggleTaskId.value = taskItem.dataset.taskId || '';
|
|
}
|
|
|
|
if (detailDeleteTaskId) {
|
|
detailDeleteTaskId.value = taskItem.dataset.taskId || '';
|
|
}
|
|
|
|
if (detailToggleIcon) {
|
|
detailToggleIcon.className = `bi ${taskItem.dataset.taskToggleIcon || 'bi-check2'} me-2`;
|
|
}
|
|
|
|
if (detailToggleText) {
|
|
detailToggleText.textContent = taskItem.dataset.taskToggleLabel || 'Отметить выполненной';
|
|
}
|
|
|
|
syncEditForm(taskItem);
|
|
|
|
if (shouldSyncHistory && taskItem.dataset.taskId) {
|
|
updateHistory(taskItem.dataset.taskId);
|
|
}
|
|
};
|
|
|
|
taskList.addEventListener('click', (event) => {
|
|
const taskItem = event.target.closest('.task-item');
|
|
if (!taskItem) {
|
|
return;
|
|
}
|
|
|
|
if (event.target.closest('form') || event.target.closest('[data-bs-toggle="dropdown"]') || event.target.closest('.dropdown-item-edit')) {
|
|
return;
|
|
}
|
|
|
|
if (event.target.closest('.dropdown-menu') && !event.target.closest('.task-open-link')) {
|
|
return;
|
|
}
|
|
|
|
const clickedLink = event.target.closest('a');
|
|
if (clickedLink && !event.target.closest('.task-open-link')) {
|
|
return;
|
|
}
|
|
|
|
event.preventDefault();
|
|
selectTask(taskItem);
|
|
});
|
|
|
|
taskList.addEventListener('keydown', (event) => {
|
|
const taskItem = event.target.closest('.task-item');
|
|
if (!taskItem || event.target !== taskItem) {
|
|
return;
|
|
}
|
|
|
|
if (event.key !== 'Enter' && event.key !== ' ') {
|
|
return;
|
|
}
|
|
|
|
event.preventDefault();
|
|
selectTask(taskItem);
|
|
});
|
|
|
|
window.addEventListener('popstate', () => {
|
|
const taskId = new URL(window.location.href).searchParams.get('task');
|
|
if (!taskId) {
|
|
return;
|
|
}
|
|
|
|
const matchingItem = document.querySelector(`.task-item[data-task-id="${CSS.escape(taskId)}"]`);
|
|
if (matchingItem) {
|
|
selectTask(matchingItem, false);
|
|
}
|
|
});
|
|
});
|