@@ -270,7 +270,8 @@ function renderBoard() {
|
|||||||
headers: { 'Content-Type': 'application/json' },
|
headers: { 'Content-Type': 'application/json' },
|
||||||
body: JSON.stringify({ status: 'Done' }),
|
body: JSON.stringify({ status: 'Done' }),
|
||||||
});
|
});
|
||||||
loadTasks();
|
initDragAndDrop();
|
||||||
|
loadTasks();
|
||||||
});
|
});
|
||||||
|
|
||||||
cardsEl.appendChild(cardEl);
|
cardsEl.appendChild(cardEl);
|
||||||
@@ -328,11 +329,13 @@ function initTasksPage() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
e.target.reset();
|
e.target.reset();
|
||||||
loadTasks();
|
initDragAndDrop();
|
||||||
|
loadTasks();
|
||||||
});
|
});
|
||||||
|
|
||||||
initTaskFilters();
|
initTaskFilters();
|
||||||
populateAgentDropdown();
|
populateAgentDropdown();
|
||||||
|
initDragAndDrop();
|
||||||
loadTasks();
|
loadTasks();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1375,3 +1378,69 @@ function renderGiteaActivity() {
|
|||||||
</div>
|
</div>
|
||||||
`).join('');
|
`).join('');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ============ DRAG AND DROP ============
|
||||||
|
let draggedTask = null;
|
||||||
|
|
||||||
|
function initDragAndDrop() {
|
||||||
|
const board = document.getElementById('board');
|
||||||
|
if (!board) return;
|
||||||
|
|
||||||
|
// Add drag listeners to columns
|
||||||
|
document.querySelectorAll('.column').forEach(column => {
|
||||||
|
column.addEventListener('dragover', handleDragOver);
|
||||||
|
column.addEventListener('drop', handleDrop);
|
||||||
|
column.addEventListener('dragleave', handleDragLeave);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleDragOver(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
e.currentTarget.classList.add('drag-over');
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleDragLeave(e) {
|
||||||
|
e.currentTarget.classList.remove('drag-over');
|
||||||
|
}
|
||||||
|
|
||||||
|
async function handleDrop(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
const column = e.currentTarget;
|
||||||
|
column.classList.remove('drag-over');
|
||||||
|
|
||||||
|
if (!draggedTask) return;
|
||||||
|
|
||||||
|
const newStatus = column.dataset.status;
|
||||||
|
if (newStatus === draggedTask.status) return;
|
||||||
|
|
||||||
|
// Update task status via API
|
||||||
|
try {
|
||||||
|
await fetch(`/api/tasks/${draggedTask.id}`, {
|
||||||
|
method: 'PATCH',
|
||||||
|
headers: { 'Content-Type': 'application/json' },
|
||||||
|
body: JSON.stringify({ status: newStatus })
|
||||||
|
});
|
||||||
|
|
||||||
|
// Reload tasks
|
||||||
|
await initDragAndDrop();
|
||||||
|
loadTasks();
|
||||||
|
} catch (err) {
|
||||||
|
console.error('Failed to update task:', err);
|
||||||
|
}
|
||||||
|
|
||||||
|
draggedTask = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
function makeTaskCardDraggable(cardEl, task) {
|
||||||
|
cardEl.draggable = true;
|
||||||
|
|
||||||
|
cardEl.addEventListener('dragstart', (e) => {
|
||||||
|
draggedTask = task;
|
||||||
|
cardEl.classList.add('dragging');
|
||||||
|
e.dataTransfer.effectAllowed = 'move';
|
||||||
|
});
|
||||||
|
|
||||||
|
cardEl.addEventListener('dragend', () => {
|
||||||
|
cardEl.classList.remove('dragging');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|||||||
@@ -1000,3 +1000,28 @@ label {
|
|||||||
flex: 1;
|
flex: 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Drag and Drop */
|
||||||
|
.task-card {
|
||||||
|
cursor: grab;
|
||||||
|
transition: transform 0.2s, box-shadow 0.2s, opacity 0.2s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.task-card:active {
|
||||||
|
cursor: grabbing;
|
||||||
|
}
|
||||||
|
|
||||||
|
.task-card.dragging {
|
||||||
|
opacity: 0.5;
|
||||||
|
transform: scale(1.02);
|
||||||
|
}
|
||||||
|
|
||||||
|
.column.drag-over {
|
||||||
|
background: var(--hover-bg);
|
||||||
|
border: 2px dashed var(--primary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.column.drag-over .column-header {
|
||||||
|
background: var(--primary);
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user