Fix drag drop: use ref for target room ID instead of elementFromPoint in mouseup (stale closure fix)
This commit is contained in:
@@ -86,6 +86,7 @@ export function BookingCalendar({ rooms, bookings, slug, onBookingCreate, onBook
|
|||||||
const [moveTargetRoomId, setMoveTargetRoomId] = useState<string | null>(null)
|
const [moveTargetRoomId, setMoveTargetRoomId] = useState<string | null>(null)
|
||||||
const [ghostPos, setGhostPos] = useState<{ x: number; y: number } | null>(null)
|
const [ghostPos, setGhostPos] = useState<{ x: number; y: number } | null>(null)
|
||||||
const movingBookingRef = useRef<Booking | null>(null)
|
const movingBookingRef = useRef<Booking | null>(null)
|
||||||
|
const moveTargetRoomIdRef = useRef<string | null>(null) // всегда актуален, без stale closure
|
||||||
const didDragRef = useRef(false)
|
const didDragRef = useRef(false)
|
||||||
movingBookingRef.current = movingBooking
|
movingBookingRef.current = movingBooking
|
||||||
|
|
||||||
@@ -486,24 +487,28 @@ export function BookingCalendar({ rooms, bookings, slug, onBookingCreate, onBook
|
|||||||
if (Math.abs(ev.clientX - startX) > 5 || Math.abs(ev.clientY - startY) > 5) {
|
if (Math.abs(ev.clientX - startX) > 5 || Math.abs(ev.clientY - startY) > 5) {
|
||||||
dragging = true
|
dragging = true
|
||||||
setMovingBooking(booking)
|
setMovingBooking(booking)
|
||||||
|
moveTargetRoomIdRef.current = booking.roomId
|
||||||
setMoveTargetRoomId(booking.roomId)
|
setMoveTargetRoomId(booking.roomId)
|
||||||
document.body.style.cursor = 'grabbing'
|
document.body.style.cursor = 'grabbing'
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
setGhostPos({ x: ev.clientX, y: ev.clientY })
|
setGhostPos({ x: ev.clientX, y: ev.clientY })
|
||||||
|
// Находим строку под курсором и запоминаем в ref (без stale closure)
|
||||||
const el = document.elementFromPoint(ev.clientX, ev.clientY)
|
const el = document.elementFromPoint(ev.clientX, ev.clientY)
|
||||||
const row = el?.closest('[data-room-id]') as HTMLElement | null
|
const row = el?.closest('[data-room-id]') as HTMLElement | null
|
||||||
if (row?.dataset.roomId) setMoveTargetRoomId(row.dataset.roomId)
|
if (row?.dataset.roomId) {
|
||||||
|
moveTargetRoomIdRef.current = row.dataset.roomId
|
||||||
|
setMoveTargetRoomId(row.dataset.roomId)
|
||||||
}
|
}
|
||||||
const onUp = (ev: MouseEvent) => {
|
}
|
||||||
|
const onUp = () => {
|
||||||
window.removeEventListener('mousemove', onMove)
|
window.removeEventListener('mousemove', onMove)
|
||||||
window.removeEventListener('mouseup', onUp)
|
window.removeEventListener('mouseup', onUp)
|
||||||
document.body.style.cursor = ''
|
document.body.style.cursor = ''
|
||||||
if (dragging) {
|
if (dragging) {
|
||||||
const el = document.elementFromPoint(ev.clientX, ev.clientY)
|
// Читаем из ref — всегда актуальное значение, не stale closure
|
||||||
const row = el?.closest('[data-room-id]') as HTMLElement | null
|
const targetRoomId = moveTargetRoomIdRef.current
|
||||||
const targetRoomId = row?.dataset.roomId
|
|
||||||
if (targetRoomId && targetRoomId !== booking.roomId) {
|
if (targetRoomId && targetRoomId !== booking.roomId) {
|
||||||
didDragRef.current = true
|
didDragRef.current = true
|
||||||
onBookingUpdate(booking.id, { roomId: targetRoomId })
|
onBookingUpdate(booking.id, { roomId: targetRoomId })
|
||||||
@@ -511,6 +516,7 @@ export function BookingCalendar({ rooms, bookings, slug, onBookingCreate, onBook
|
|||||||
setMovingBooking(null)
|
setMovingBooking(null)
|
||||||
setMoveTargetRoomId(null)
|
setMoveTargetRoomId(null)
|
||||||
setGhostPos(null)
|
setGhostPos(null)
|
||||||
|
moveTargetRoomIdRef.current = null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
window.addEventListener('mousemove', onMove)
|
window.addEventListener('mousemove', onMove)
|
||||||
|
|||||||
Reference in New Issue
Block a user