Fix drag and drop

This commit is contained in:
2025-10-18 22:15:18 +02:00
parent b7388c2ccc
commit 4ae00cac87

View File

@@ -188,67 +188,83 @@ const HomePage = () => {
let newHabits = [...habits]; let newHabits = [...habits];
// If dropping into uncategorized, always unset category // Helper to update local storage and UI instantly
const updateLocalOrder = (habitsArr) => {
localStorage.setItem('habitgrid_data', JSON.stringify(habitsArr));
setHabits(habitsArr);
};
// Collect async remote updates to fire after local update
let remoteUpdates = [];
if (destination.droppableId === 'uncategorized') { if (destination.droppableId === 'uncategorized') {
let items, removed; let items, removed;
if (source.droppableId === 'uncategorized') { if (source.droppableId === 'uncategorized') {
// Reorder within uncategorized
items = Array.from(uncategorized); items = Array.from(uncategorized);
[removed] = items.splice(source.index, 1); [removed] = items.splice(source.index, 1);
} else { } else {
// Move from category to uncategorized
items = Array.from(uncategorized); items = Array.from(uncategorized);
const sourceItems = Array.from(grouped[source.droppableId]); const sourceItems = Array.from(grouped[source.droppableId]);
[removed] = sourceItems.splice(source.index, 1); [removed] = sourceItems.splice(source.index, 1);
removed.category = ''; removed.category = '';
grouped[source.droppableId] = sourceItems; grouped[source.droppableId] = sourceItems;
} }
// Always set category to ''
removed.category = ''; removed.category = '';
items.splice(destination.index, 0, removed); items.splice(destination.index, 0, removed);
items.forEach((h, i) => updateHabit(h.id, { sortOrder: i, category: '' })); items.forEach((h, i) => {
h.sortOrder = i;
h.category = '';
remoteUpdates.push(updateHabit(h.id, { sortOrder: i, category: '' }));
});
newHabits = [ newHabits = [
...items, ...items,
...Object.values(grouped).flat() ...Object.values(grouped).flat()
]; ];
updateLocalOrder(newHabits);
} else if (source.droppableId === 'uncategorized' && grouped[destination.droppableId]) { } else if (source.droppableId === 'uncategorized' && grouped[destination.droppableId]) {
// Move from uncategorized to category
const items = Array.from(uncategorized); const items = Array.from(uncategorized);
const [removed] = items.splice(source.index, 1); const [removed] = items.splice(source.index, 1);
removed.category = destination.droppableId; removed.category = destination.droppableId;
const destItems = Array.from(grouped[destination.droppableId] || []); const destItems = Array.from(grouped[destination.droppableId] || []);
destItems.splice(destination.index, 0, removed); destItems.splice(destination.index, 0, removed);
destItems.forEach((h, i) => updateHabit(h.id, { sortOrder: i, category: h.category })); destItems.forEach((h, i) => {
h.sortOrder = i;
remoteUpdates.push(updateHabit(h.id, { sortOrder: i, category: h.category }));
});
newHabits = [ newHabits = [
...items, ...items,
...Object.values({ ...grouped, [destination.droppableId]: destItems }).flat() ...Object.values({ ...grouped, [destination.droppableId]: destItems }).flat()
]; ];
updateLocalOrder(newHabits);
} else if (grouped[source.droppableId] && grouped[destination.droppableId]) { } else if (grouped[source.droppableId] && grouped[destination.droppableId]) {
// Move within or between categories
const sourceItems = Array.from(grouped[source.droppableId]); const sourceItems = Array.from(grouped[source.droppableId]);
const [removed] = sourceItems.splice(source.index, 1); const [removed] = sourceItems.splice(source.index, 1);
if (source.droppableId === destination.droppableId) { if (source.droppableId === destination.droppableId) {
// Reorder within same category
sourceItems.splice(destination.index, 0, removed); sourceItems.splice(destination.index, 0, removed);
sourceItems.forEach((h, i) => updateHabit(h.id, { sortOrder: i, category: h.category })); sourceItems.forEach((h, i) => {
h.sortOrder = i;
remoteUpdates.push(updateHabit(h.id, { sortOrder: i, category: h.category }));
});
grouped[source.droppableId] = sourceItems; grouped[source.droppableId] = sourceItems;
} else { } else {
// Move to another category
const destItems = Array.from(grouped[destination.droppableId] || []); const destItems = Array.from(grouped[destination.droppableId] || []);
removed.category = destination.droppableId; removed.category = destination.droppableId;
destItems.splice(destination.index, 0, removed); destItems.splice(destination.index, 0, removed);
destItems.forEach((h, i) => updateHabit(h.id, { sortOrder: i, category: h.category })); destItems.forEach((h, i) => {
h.sortOrder = i;
remoteUpdates.push(updateHabit(h.id, { sortOrder: i, category: h.category }));
});
grouped[source.droppableId] = sourceItems; grouped[source.droppableId] = sourceItems;
grouped[destination.droppableId] = destItems; grouped[destination.droppableId] = destItems;
} }
// Flatten
newHabits = [ newHabits = [
...uncategorized, ...uncategorized,
...Object.values(grouped).flat() ...Object.values(grouped).flat()
]; ];
updateLocalOrder(newHabits);
} }
// Force immediate UI update after all updates // Fire remote updates async, do not block UI
loadHabits(); Promise.allSettled(remoteUpdates);
}} }}
> >
<div className="space-y-6"> <div className="space-y-6">