Skip to content

Commit 4e16b77

Browse files
committed
fix(course-outline): correct library drag targets
1 parent 2b5e8dc commit 4e16b77

3 files changed

Lines changed: 43 additions & 3 deletions

File tree

src/course-outline/OutlineNode.tsx

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -339,9 +339,11 @@ const OutlineNode = ({
339339
) :
340340
undefined;
341341

342-
const isDroppable = depth === 2
343-
? (parentSubsection as any)?.actions?.childAddable ?? false
344-
: actions.childAddable || (parentSection?.actions?.childAddable ?? false);
342+
// Node is droppable when it can be a same-level reorder target or can accept children
343+
const isDroppable = Boolean(actions.draggable
344+
|| actions.childAddable
345+
|| (depth === 1 && parentSection?.actions?.childAddable)
346+
|| (depth === 2 && parentSubsection?.actions?.childAddable));
345347

346348
const showPaste = depth === 1 && blk.enableCopyPasteUnits && showPasteUnit && sharedClipboardData;
347349

src/course-outline/drag-helper/DraggableList.test.tsx

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -260,6 +260,43 @@ describe('DraggableList — drag-local tree ref', () => {
260260
});
261261
});
262262

263+
describe('unit drag over non-childAddable subsection via contained-unit collision', () => {
264+
it('must not preview or commit when over unit inside childAddable=false subsection', () => {
265+
// sub-B has childAddable=false (e.g. library subsection) but draggable=true
266+
const unitA = makeUnit('unit-A');
267+
const unitB = makeUnit('unit-B');
268+
const subsectionA = makeSubsection('sub-A', [unitA]);
269+
const subsectionB = makeSubsection('sub-B', [unitB]);
270+
subsectionB.actions.childAddable = false;
271+
const section1 = makeSection('sec-1', [subsectionA]);
272+
const section2 = makeSection('sec-2', [subsectionB]);
273+
const items = [section1, section2];
274+
275+
const callbacks = renderList(items);
276+
277+
expect(mockDndHandlers.current).not.toBeNull();
278+
279+
// Start dragging unit-A from sub-A.
280+
fireDragStart('unit-A', 'Unit A', 'vertical');
281+
282+
// Drag over unit-B inside sub-B (childAddable=false).
283+
fireDragOver(
284+
'unit-A',
285+
'unit-B',
286+
{ category: 'vertical' },
287+
{ category: 'vertical' },
288+
);
289+
290+
// unitDragOver guard should fire — no preview.
291+
expect(callbacks.onPreviewTreeChange).not.toHaveBeenCalled();
292+
293+
// Drag end — no commit.
294+
fireDragEnd('unit-A', 'unit-B');
295+
296+
expect(callbacks.onUnitDrop).not.toHaveBeenCalled();
297+
});
298+
});
299+
263300
describe('drag cancellations reset ref', () => {
264301
it('resets drag-local state on cancel', () => {
265302
const section1 = makeSection('sec-1', [makeSubsection('sub-A')]);

src/course-outline/drag-helper/DraggableList.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,7 @@ const DraggableList = ({
203203
activeInfo.parent?.id === overInfo.parent?.id
204204
|| activeInfo.parent?.id === overInfo.item.id
205205
|| (activeInfo.parent?.category === overInfo.category && !overInfo.item.actions.childAddable)
206+
|| (activeInfo.category === overInfo.category && !overInfo.parent?.actions.childAddable)
206207
) {
207208
return;
208209
}

0 commit comments

Comments
 (0)