refactor(web): extract allocation multi-drag session

This commit is contained in:
2026-04-01 11:22:18 +02:00
parent 5402189158
commit 510459fbff
5 changed files with 249 additions and 37 deletions
+17 -37
View File
@@ -18,6 +18,7 @@ import {
startAllocationMultiDrag,
updateAllocationMultiDrag,
} from "./timelineAllocationMultiDrag.js";
import { beginAllocationMultiDragSession } from "./timelineAllocationMultiDragSession.js";
import { resolveAllocationRelease } from "./timelineAllocationRelease.js";
import { createAllocationDragState } from "./timelineAllocationDragState.js";
import { cleanupTimelineDragState } from "./timelineDragCleanup.js";
@@ -593,43 +594,22 @@ export function useTimelineDrag({
const isMultiSelected = isAllocationMultiSelected(ms, opts.allocationId);
if (isMultiSelected) {
// ── Multi-drag: move/resize all selected allocations together ──
const startMouseX = e.clientX;
const dragMode = opts.mode;
const initialMultiDragState = startAllocationMultiDrag(ms, dragMode);
setMultiSelectState(initialMultiDragState);
multiSelectRef.current = initialMultiDragState;
multiSelectCleanupRef.current?.();
function handleMultiMove(ev: MouseEvent) {
const deltaX = ev.clientX - startMouseX;
const daysDelta = pixelsToDays(deltaX, cellWidthRef.current);
const updated = updateAllocationMultiDrag(multiSelectRef.current, daysDelta);
if (!updated) return;
setMultiSelectState(updated);
multiSelectRef.current = updated;
}
function handleMultiUp(ev: MouseEvent) {
multiSelectCleanupRef.current?.();
multiSelectCleanupRef.current = null;
const finalDelta = pixelsToDays(ev.clientX - startMouseX, cellWidthRef.current);
const finalized = finalizeAllocationMultiDrag(multiSelectRef.current);
setMultiSelectState(finalized);
multiSelectRef.current = finalized;
if (finalDelta !== 0) {
// Pass IDs from ref to avoid stale closure in the callback
const ids = finalized.selectedAllocationIds;
onMultiDragCompleteRef.current?.(finalDelta, dragMode, ids);
}
}
multiSelectCleanupRef.current = attachDocumentMouseDrag(document, handleMultiMove, handleMultiUp);
beginAllocationMultiDragSession({
startMouseX: e.clientX,
dragMode: opts.mode,
documentTarget: document,
cleanupRef: multiSelectCleanupRef,
stateRef: multiSelectRef,
setState: setMultiSelectState,
startState: startAllocationMultiDrag,
updateState: updateAllocationMultiDrag,
finalizeState: finalizeAllocationMultiDrag,
toDaysDelta: (deltaX) => pixelsToDays(deltaX, cellWidthRef.current),
onComplete: (daysDelta, finalized) => {
onMultiDragCompleteRef.current?.(daysDelta, opts.mode, finalized.selectedAllocationIds);
},
attachDrag: attachDocumentMouseDrag,
});
return;
}