refactor(web): extract timeline multi-select helpers

This commit is contained in:
2026-04-01 09:50:03 +02:00
parent 3abb3bc865
commit 43f04d66c8
3 changed files with 178 additions and 21 deletions
+10 -21
View File
@@ -12,6 +12,11 @@ import {
scheduleLivePreview,
type LivePreviewSession,
} from "./timelineLivePreview.js";
import {
createMultiSelectState,
finalizeMultiSelectDraft,
updateMultiSelectDraft,
} from "./timelineMultiSelect.js";
import { getTouchPoint, resolveTouchDragDecision } from "./timelineTouch.js";
const DRAG_CLICK_THRESHOLD_PX = 5;
@@ -958,19 +963,14 @@ export function useTimelineDrag({
if (e.button !== 2) return;
e.preventDefault();
const initial: MultiSelectState = {
isSelecting: true,
startX: e.clientX,
startY: e.clientY,
currentX: e.clientX,
currentY: e.clientY,
const initial = createMultiSelectState<MultiSelectState>(e.clientX, e.clientY, {
selectedAllocationIds: [],
selectedResourceIds: [],
dateRange: null,
multiDragDaysDelta: 0,
isMultiDragging: false,
multiDragMode: "move",
};
});
multiSelectRef.current = initial;
setMultiSelectState(initial);
multiSelectCleanupRef.current?.();
@@ -979,11 +979,7 @@ export function useTimelineDrag({
const ms = multiSelectRef.current;
if (!ms.isSelecting) return;
const updated: MultiSelectState = {
...ms,
currentX: ev.clientX,
currentY: ev.clientY,
};
const updated = updateMultiSelectDraft(ms, ev.clientX, ev.clientY);
multiSelectRef.current = updated;
setMultiSelectState(updated);
}
@@ -995,9 +991,8 @@ export function useTimelineDrag({
const ms = multiSelectRef.current;
if (!ms.isSelecting) return;
const distance = Math.hypot(ev.clientX - ms.startX, ev.clientY - ms.startY);
if (distance < 5) {
const finished = finalizeMultiSelectDraft(ms, ev.clientX, ev.clientY);
if (!finished) {
// Minimal movement → not a drag selection, reset.
// Let existing onContextMenu handlers on allocation blocks handle right-click.
multiSelectRef.current = INITIAL_MULTI_SELECT;
@@ -1009,12 +1004,6 @@ export function useTimelineDrag({
// isSelecting is set to false to indicate the drag is done, but the
// rectangle data (startX/Y, currentX/Y) is preserved so TimelineView
// can resolve which allocations/resources fall within the selection.
const finished: MultiSelectState = {
...ms,
isSelecting: false,
currentX: ev.clientX,
currentY: ev.clientY,
};
multiSelectRef.current = finished;
setMultiSelectState(finished);
}