HH/static/js/project-board.js
ismail c5f76b3855
Some checks are pending
Build and Push Docker Image / build (push) Waiting to run
updates
2026-05-11 14:45:30 +03:00

118 lines
4.5 KiB
JavaScript

/**
* Project Board JavaScript
* Handles drag and drop reordering for kanban board
*/
(function() {
'use strict';
// Initialize drag and drop when DOM is ready
document.addEventListener('DOMContentLoaded', initDragAndDrop);
// Re-initialize after HTMX swaps
document.body.addEventListener('htmx:afterSwap', function(evt) {
initDragAndDrop();
});
function initDragAndDrop() {
const taskLists = document.querySelectorAll('[id^="phase-tasks-"]');
taskLists.forEach(list => {
const tasks = list.querySelectorAll('.task-item');
tasks.forEach(task => {
task.draggable = true;
task.addEventListener('dragstart', function(e) {
e.dataTransfer.effectAllowed = 'move';
e.dataTransfer.setData('text/plain', task.dataset.taskId);
task.classList.add('dragging');
});
task.addEventListener('dragend', function() {
task.classList.remove('dragging');
document.querySelectorAll('.task-item').forEach(t => t.classList.remove('drag-over'));
});
task.addEventListener('dragover', function(e) {
e.preventDefault();
e.dataTransfer.dropEffect = 'move';
const draggingTask = document.querySelector('.task-item.dragging');
if (draggingTask && draggingTask !== task) {
task.classList.add('drag-over');
}
});
task.addEventListener('dragleave', function() {
task.classList.remove('drag-over');
});
task.addEventListener('drop', function(e) {
e.preventDefault();
task.classList.remove('drag-over');
const draggedId = e.dataTransfer.getData('text/plain');
const draggedTask = document.querySelector(`[data-task-id="${draggedId}"]`);
if (draggedTask && draggedTask !== task) {
const list = task.parentElement;
const rect = task.getBoundingClientRect();
const midpoint = rect.top + rect.height / 2;
if (e.clientY < midpoint) {
list.insertBefore(draggedTask, task);
} else {
list.insertBefore(draggedTask, task.nextSibling);
}
// Update order via HTMX
updateTaskOrder(list);
}
});
});
// Allow dropping at the end of the list
list.addEventListener('dragover', function(e) {
e.preventDefault();
const draggingTask = document.querySelector('.task-item.dragging');
if (draggingTask) {
list.appendChild(draggingTask);
}
});
});
}
function updateTaskOrder(list) {
const tasks = list.querySelectorAll('.task-item');
const taskIds = Array.from(tasks).map(t => t.dataset.taskId);
// Get phase info from list ID
const listId = list.id; // e.g., "phase-tasks-pdca-plan"
const parts = listId.split('-');
const phaseType = parts[2];
const phaseKey = parts[3];
// Update each task's order
taskIds.forEach((taskId, index) => {
const csrfToken = document.querySelector('[name=csrfmiddlewaretoken]')?.value;
fetch(`/projects/${getProjectId()}/htmx/tasks/${taskId}/reorder/`, {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'X-CSRFToken': csrfToken || '',
},
body: `order=${index}`
}).catch(err => console.error('Failed to update task order:', err));
});
}
function getProjectId() {
// Extract project ID from URL
const match = window.location.pathname.match(/\/projects\/([a-f0-9-]+)\//);
return match ? match[1] : '';
}
})();