From fb8286651265c9540897ce2884be59e61aa78ae4 Mon Sep 17 00:00:00 2001 From: WithoutPants <53250216+WithoutPants@users.noreply.github.com> Date: Thu, 5 Sep 2024 11:25:30 +1000 Subject: [PATCH] Don't show move drop target on non-move drag operations (#5219) --- .../Shared/GridCard/dragMoveSelect.ts | 23 ++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/ui/v2.5/src/components/Shared/GridCard/dragMoveSelect.ts b/ui/v2.5/src/components/Shared/GridCard/dragMoveSelect.ts index caae45260..d5ca0ecb9 100644 --- a/ui/v2.5/src/components/Shared/GridCard/dragMoveSelect.ts +++ b/ui/v2.5/src/components/Shared/GridCard/dragMoveSelect.ts @@ -1,11 +1,26 @@ import { useState } from "react"; import { useListContextOptional } from "src/components/List/ListProvider"; +// Enum representing the possible sides for a drag operation. export enum DragSide { BEFORE, AFTER, } +/** + * Hook to manage drag and move selection functionality. + * Dragging while selecting will allow the user to select multiple items. + * Dragging from the drag handle will allow the user to move the item or selected items. + * + * @param props - The properties for the hook. + * @param props.selecting - Whether the one or more items have been selected. + * @param props.selected - Whether this item is currently selected. + * @param props.onSelectedChanged - Callback when the selected state changes. + * @param props.objectId - The ID of this object. + * @param props.onMove - Callback when a move operation occurs. + * + * @returns An object containing the drag event handlers and state. + */ export function useDragMoveSelect(props: { selecting: boolean; selected: boolean; @@ -15,8 +30,12 @@ export function useDragMoveSelect(props: { }) { const { selectedIds } = useListContextOptional(); + // true if the mouse is over the drag handle const [inHandle, setInHandle] = useState(false); + + // true if this is the source of a move operation const [moveSrc, setMoveSrc] = useState(false); + // the target side for a move operation const [moveTarget, setMoveTarget] = useState(); const canSelect = props.onSelectedChanged && props.selecting; @@ -75,6 +94,7 @@ export function useDragMoveSelect(props: { ev.dataTransfer.dropEffect = "copy"; ev.preventDefault(); } else if (ev.dataTransfer.effectAllowed === "move" && !moveSrc) { + // don't allow move on self doSetMoveTarget(event); ev.dataTransfer.dropEffect = "move"; ev.preventDefault(); @@ -92,7 +112,8 @@ export function useDragMoveSelect(props: { } function onDragOver(event: React.DragEvent) { - if (event.dataTransfer.effectAllowed === "move" && moveSrc) { + // only set move target if move is allowed, or if this is not the source of the move + if (event.dataTransfer.effectAllowed !== "move" || moveSrc) { return; }