fix(outliner): move entire subtree with all children during drag and drop
MindSift CI & Docker Release / Build, Test in Container & Push (push) Successful in 1m4s

This commit is contained in:
sandrodach committed 2026-10-27 16:00:03 +01:00
1 parent 266026da4c
commit 1bdd7d245d
2 files changed
+96 -14

No files matched your search

@@ -282,10 +282,29 @@ export const OutlinerTree: React.FC<OutlinerTreeProps> = ({
setDraggedIndex(index);
}, []);
const handleDragOverBlock = useCallback((e: React.DragEvent, index: number) => {
e.preventDefault();
setDragOverIndex(index);
}, []);
const handleDragOverBlock = useCallback(
(e: React.DragEvent, index: number) => {
e.preventDefault();
if (draggedIndex !== null) {
const parentLevel = Math.max(0, blocks[draggedIndex]?.level || 0);
let count = 1;
for (let i = draggedIndex + 1; i < blocks.length; i++) {
if (Math.max(0, blocks[i].level || 0) > parentLevel) {
count++;
} else {
break;
}
}
// Do not allow dropping inside its own subtree (self or descendants)
if (index >= draggedIndex && index < draggedIndex + count) {
setDragOverIndex(null);
return;
}
}
setDragOverIndex(index);
},
[blocks, draggedIndex]
);
const handleDropBlock = useCallback(
(targetIndex: number) => {
@@ -294,6 +313,20 @@ export const OutlinerTree: React.FC<OutlinerTreeProps> = ({
setDragOverIndex(null);
return;
}
const parentLevel = Math.max(0, blocks[draggedIndex]?.level || 0);
let count = 1;
for (let i = draggedIndex + 1; i < blocks.length; i++) {
if (Math.max(0, blocks[i].level || 0) > parentLevel) {
count++;
} else {
break;
}
}
if (targetIndex >= draggedIndex && targetIndex < draggedIndex + count) {
setDraggedIndex(null);
setDragOverIndex(null);
return;
}
const movingBlock = blocks[draggedIndex];
if (movingBlock) {
onMoveBlock(movingBlock.id, targetIndex, movingBlock.level);
@@ -372,7 +405,18 @@ export const OutlinerTree: React.FC<OutlinerTreeProps> = ({
})}
{canEdit && (
<div className="pt-2 pl-2">
<div
className={`pt-2 pl-2 transition-colors ${
dragOverIndex === blocks.length ? 'border-t-2 border-accent bg-accent/10 rounded' : ''
}`}
onDragOver={(e) => {
e.preventDefault();
if (draggedIndex !== null) {
setDragOverIndex(blocks.length);
}
}}
onDrop={() => handleDropBlock(blocks.length)}
>
<button
type="button"
onClick={() => {