Adds HTML5 drag-to-reorder for .sv-card elements in Sacred Valley. The pure moveId helper is unit-tested. Drop calls PUT /api/dashboard/layout to persist the new card_order; DOM reflects the new order immediately. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
29 lines
1.3 KiB
JavaScript
29 lines
1.3 KiB
JavaScript
export function moveId(order, dragId, beforeId) {
|
|
if (dragId === beforeId) return [...order];
|
|
const out = order.filter(id => id !== dragId);
|
|
if (beforeId == null) { out.push(dragId); return out; }
|
|
const i = out.indexOf(beforeId);
|
|
if (i < 0) { out.push(dragId); return out; }
|
|
out.splice(i, 0, dragId);
|
|
return out;
|
|
}
|
|
|
|
// Wires HTML5 drag on .sv-card elements in `grid`. onReorder(newOrderIds) fires
|
|
// after a drop. Drag handle = the whole card (cursor:grab on the title via CSS).
|
|
export function attachReorder(grid, onReorder) {
|
|
let dragId = null;
|
|
grid.querySelectorAll('.sv-card').forEach(card => {
|
|
card.draggable = true;
|
|
card.addEventListener('dragstart', () => { dragId = card.dataset.cardId; card.classList.add('dragging'); });
|
|
card.addEventListener('dragend', () => { card.classList.remove('dragging'); dragId = null; });
|
|
card.addEventListener('dragover', e => { e.preventDefault(); card.classList.add('drag-over'); });
|
|
card.addEventListener('dragleave', () => card.classList.remove('drag-over'));
|
|
card.addEventListener('drop', e => {
|
|
e.preventDefault(); card.classList.remove('drag-over');
|
|
if (!dragId || dragId === card.dataset.cardId) return;
|
|
const ids = [...grid.querySelectorAll('.sv-card')].map(c => c.dataset.cardId);
|
|
onReorder(moveId(ids, dragId, card.dataset.cardId));
|
|
});
|
|
});
|
|
}
|