diff --git a/frontend/faraday/lib/TileLayout.tsx b/frontend/faraday/lib/TileLayout.tsx index 1fe0e08fb..a7ade31af 100644 --- a/frontend/faraday/lib/TileLayout.tsx +++ b/frontend/faraday/lib/TileLayout.tsx @@ -423,18 +423,24 @@ const OverlayNode = ({ layoutNode, layoutTreeState, dispatch, setRef, delete } }, hover: (_, monitor) => { - if (monitor.isOver({ shallow: true }) && monitor.canDrop()) { - const dragItem = monitor.getItem>(); - console.log("computing operation", layoutNode, dragItem, layoutTreeState.pendingAction); - dispatch({ - type: LayoutTreeActionType.ComputeMove, - node: layoutNode, - nodeToMove: dragItem, - direction: determineDropDirection( - overlayRef.current?.getBoundingClientRect(), - monitor.getClientOffset() - ), - } as LayoutTreeComputeMoveNodeAction); + if (monitor.isOver({ shallow: true })) { + if (monitor.canDrop()) { + const dragItem = monitor.getItem>(); + console.log("computing operation", layoutNode, dragItem, layoutTreeState.pendingAction); + dispatch({ + type: LayoutTreeActionType.ComputeMove, + node: layoutNode, + nodeToMove: dragItem, + direction: determineDropDirection( + overlayRef.current?.getBoundingClientRect(), + monitor.getClientOffset() + ), + } as LayoutTreeComputeMoveNodeAction); + } else { + dispatch({ + type: LayoutTreeActionType.ClearPendingAction, + }); + } } }, }), diff --git a/frontend/faraday/lib/layoutState.ts b/frontend/faraday/lib/layoutState.ts index df318a207..b55d9718e 100644 --- a/frontend/faraday/lib/layoutState.ts +++ b/frontend/faraday/lib/layoutState.ts @@ -70,6 +70,9 @@ function layoutTreeStateReducerInner(layoutTreeState: LayoutTreeState, act case LayoutTreeActionType.ComputeMove: computeMoveNode(layoutTreeState, action as LayoutTreeComputeMoveNodeAction); break; + case LayoutTreeActionType.ClearPendingAction: + clearPendingAction(layoutTreeState); + break; case LayoutTreeActionType.CommitPendingAction: if (!layoutTreeState?.pendingAction) { console.error("unable to commit pending action, does not exist"); @@ -129,6 +132,10 @@ function computeMoveNode( const grandparent = lazy(() => findParent(rootNode, parent().id)); const indexInParent = lazy(() => parent()?.children.findIndex((child) => node.id === child.id)); const indexInGrandparent = lazy(() => grandparent()?.children.findIndex((child) => parent().id === child.id)); + const nodeToMoveParent = lazy(() => findParent(rootNode, nodeToMove.id)); + const nodeToMoveIndexInParent = lazy(() => + nodeToMoveParent()?.children.findIndex((child) => nodeToMove.id === child.id) + ); const isRoot = rootNode.id === node.id; switch (direction) { @@ -268,6 +275,7 @@ function computeMoveNode( }; console.log("swapAction", swapAction); layoutTreeState.pendingAction = swapAction; + return; } else { console.warn("cannot swap"); } @@ -276,13 +284,21 @@ function computeMoveNode( throw new Error(`Invalid direction: ${direction}`); } - if (newMoveOperation) + if ( + newMoveOperation?.parentId !== nodeToMoveParent()?.id || + (newMoveOperation.index !== nodeToMoveIndexInParent() && + newMoveOperation.index !== nodeToMoveIndexInParent() + 1) + ) layoutTreeState.pendingAction = { type: LayoutTreeActionType.Move, ...newMoveOperation, } as LayoutTreeMoveNodeAction; } +function clearPendingAction(layoutTreeState: LayoutTreeState) { + layoutTreeState.pendingAction = undefined; +} + function moveNode(layoutTreeState: LayoutTreeState, action: LayoutTreeMoveNodeAction) { const rootNode = layoutTreeState.rootNode; console.log("moveNode", action, layoutTreeState.rootNode); @@ -305,7 +321,7 @@ function moveNode(layoutTreeState: LayoutTreeState, action: LayoutTreeMove // If moving under the same parent, we need to make sure that we are removing the child from its old position, not its new one. // If the new index is before the old index, we need to start our search for the node to delete after the new index position. - if (oldParent?.id === parent.id) { + if (oldParent && parent && oldParent.id === parent.id) { const curIndexInParent = parent.children!.indexOf(node); if (curIndexInParent >= action.index) { startingIndex = action.index + 1; diff --git a/frontend/faraday/lib/model.ts b/frontend/faraday/lib/model.ts index 137f4cecc..f41aafc3e 100644 --- a/frontend/faraday/lib/model.ts +++ b/frontend/faraday/lib/model.ts @@ -33,10 +33,11 @@ export type MoveOperation = { * Types of actions that modify the layout tree. */ export enum LayoutTreeActionType { - ComputeMove = "computeMove", + ComputeMove = "compute", Move = "move", Swap = "swap", CommitPendingAction = "commit", + ClearPendingAction = "clear", ResizeNode = "resize", InsertNode = "insert", DeleteNode = "delete", @@ -116,6 +117,13 @@ export interface LayoutTreeDeleteNodeAction extends LayoutTreeAction { nodeId: string; } +/** + * Action for clearing the pendingAction field from the layout tree state. + */ +export interface LayoutTreeClearPendingAction extends LayoutTreeAction { + type: LayoutTreeActionType.ClearPendingAction; +} + /** * Represents the state of a layout tree. *