mirror of
https://github.com/wavetermdev/waveterm.git
synced 2024-12-21 16:38:23 +01:00
Fix bug in TileLayout where computeMoveNode had stale node data (#361)
This was hard to debug. It manifested in nodes that had been collapsed into their parent. When a node was dragged over the recently-collapsed node, the placeholder would show the action as if the flex direction was reversed. It turns out useDrag has trouble tracking changes to the LayoutNode objects. For now, I am just finding the nodes again in the computeMoveNode function. Later when I redo the drag system, I will fix this better.
This commit is contained in:
parent
f3940f7456
commit
9b12aa9882
@ -303,8 +303,8 @@ const OverlayNode = memo(({ node, layoutModel }: OverlayNodeProps) => {
|
||||
() => ({
|
||||
accept: dragItemType,
|
||||
canDrop: (_, monitor) => {
|
||||
const dragItem = monitor.getItem<LayoutNode>();
|
||||
if (monitor.isOver({ shallow: true }) && dragItem?.id !== node.id) {
|
||||
const dragItemId = monitor.getItem<string>();
|
||||
if (monitor.isOver({ shallow: true }) && dragItemId !== node.id) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@ -325,8 +325,8 @@ const OverlayNode = memo(({ node, layoutModel }: OverlayNodeProps) => {
|
||||
offset.y -= containerRect.y;
|
||||
layoutModel.treeReducer({
|
||||
type: LayoutTreeActionType.ComputeMove,
|
||||
node: node,
|
||||
nodeToMove: dragItem,
|
||||
nodeId: node.id,
|
||||
nodeToMoveId: dragItem.id,
|
||||
direction: determineDropDirection(additionalProps.rect, offset),
|
||||
} as LayoutTreeComputeMoveNodeAction);
|
||||
} else {
|
||||
@ -337,7 +337,7 @@ const OverlayNode = memo(({ node, layoutModel }: OverlayNodeProps) => {
|
||||
}
|
||||
}),
|
||||
}),
|
||||
[node, additionalProps?.rect, layoutModel.displayContainerRef, layoutModel.onDrop, layoutModel.treeReducer]
|
||||
[node.id, additionalProps?.rect, layoutModel.displayContainerRef, layoutModel.onDrop, layoutModel.treeReducer]
|
||||
);
|
||||
|
||||
// Register the overlay node as a drop target
|
||||
|
@ -39,27 +39,40 @@ export const DEFAULT_MAX_CHILDREN = 5;
|
||||
*/
|
||||
export function computeMoveNode(layoutState: LayoutTreeState, computeInsertAction: LayoutTreeComputeMoveNodeAction) {
|
||||
const rootNode = layoutState.rootNode;
|
||||
const { node, nodeToMove, direction } = computeInsertAction;
|
||||
const { nodeId, nodeToMoveId, direction } = computeInsertAction;
|
||||
if (!nodeId || !nodeToMoveId) {
|
||||
console.warn("either nodeId or nodeToMoveId not set", nodeId, nodeToMoveId);
|
||||
return;
|
||||
}
|
||||
if (direction === undefined) {
|
||||
console.warn("No direction provided for insertItemInDirection");
|
||||
return;
|
||||
}
|
||||
|
||||
if (node.id === nodeToMove.id) {
|
||||
if (nodeId === nodeToMoveId) {
|
||||
console.warn("Cannot compute move node action since both nodes are equal");
|
||||
return;
|
||||
}
|
||||
|
||||
let newMoveOperation: MoveOperation;
|
||||
const parent = lazy(() => findParent(rootNode, node.id));
|
||||
const parent = lazy(() => findParent(rootNode, nodeId));
|
||||
const grandparent = lazy(() => findParent(rootNode, parent().id));
|
||||
const indexInParent = lazy(() => parent()?.children.findIndex((child) => node.id === child.id));
|
||||
const indexInParent = lazy(() => parent()?.children.findIndex((child) => nodeId === child.id));
|
||||
const indexInGrandparent = lazy(() => grandparent()?.children.findIndex((child) => parent().id === child.id));
|
||||
const nodeToMoveParent = lazy(() => findParent(rootNode, nodeToMove.id));
|
||||
const nodeToMoveParent = lazy(() => findParent(rootNode, nodeToMoveId));
|
||||
const nodeToMoveIndexInParent = lazy(() =>
|
||||
nodeToMoveParent()?.children.findIndex((child) => nodeToMove.id === child.id)
|
||||
nodeToMoveParent()?.children.findIndex((child) => nodeToMoveId === child.id)
|
||||
);
|
||||
const isRoot = rootNode.id === node.id;
|
||||
const isRoot = rootNode.id === nodeId;
|
||||
|
||||
// TODO: this should not be necessary. The drag layer is having trouble tracking changes to the LayoutNode fields, so I need to grab the node again here to get the latest data.
|
||||
const node = findNode(rootNode, nodeId);
|
||||
const nodeToMove = findNode(rootNode, nodeToMoveId);
|
||||
|
||||
if (!node || !nodeToMove) {
|
||||
console.warn("node or nodeToMove not set", nodeId, nodeToMoveId);
|
||||
return;
|
||||
}
|
||||
|
||||
switch (direction) {
|
||||
case DropDirection.OuterTop:
|
||||
@ -77,7 +90,7 @@ export function computeMoveNode(layoutState: LayoutTreeState, computeInsertActio
|
||||
}
|
||||
case DropDirection.Top:
|
||||
if (node.flexDirection === FlexDirection.Column) {
|
||||
newMoveOperation = { parentId: node.id, index: 0, node: nodeToMove };
|
||||
newMoveOperation = { parentId: nodeId, index: 0, node: nodeToMove };
|
||||
} else {
|
||||
if (isRoot)
|
||||
newMoveOperation = {
|
||||
@ -110,7 +123,7 @@ export function computeMoveNode(layoutState: LayoutTreeState, computeInsertActio
|
||||
}
|
||||
case DropDirection.Bottom:
|
||||
if (node.flexDirection === FlexDirection.Column) {
|
||||
newMoveOperation = { parentId: node.id, index: 1, node: nodeToMove };
|
||||
newMoveOperation = { parentId: nodeId, index: 1, node: nodeToMove };
|
||||
} else {
|
||||
if (isRoot)
|
||||
newMoveOperation = {
|
||||
@ -143,7 +156,7 @@ export function computeMoveNode(layoutState: LayoutTreeState, computeInsertActio
|
||||
}
|
||||
case DropDirection.Left:
|
||||
if (node.flexDirection === FlexDirection.Row) {
|
||||
newMoveOperation = { parentId: node.id, index: 0, node: nodeToMove };
|
||||
newMoveOperation = { parentId: nodeId, index: 0, node: nodeToMove };
|
||||
} else {
|
||||
const parentNode = parent();
|
||||
if (parentNode)
|
||||
@ -169,7 +182,7 @@ export function computeMoveNode(layoutState: LayoutTreeState, computeInsertActio
|
||||
}
|
||||
case DropDirection.Right:
|
||||
if (node.flexDirection === FlexDirection.Row) {
|
||||
newMoveOperation = { parentId: node.id, index: 1, node: nodeToMove };
|
||||
newMoveOperation = { parentId: nodeId, index: 1, node: nodeToMove };
|
||||
} else {
|
||||
const parentNode = parent();
|
||||
if (parentNode)
|
||||
@ -181,11 +194,11 @@ export function computeMoveNode(layoutState: LayoutTreeState, computeInsertActio
|
||||
}
|
||||
break;
|
||||
case DropDirection.Center:
|
||||
if (node.id !== rootNode.id && nodeToMove.id !== rootNode.id) {
|
||||
if (nodeId !== rootNode.id && nodeToMoveId !== rootNode.id) {
|
||||
const swapAction: LayoutTreeSwapNodeAction = {
|
||||
type: LayoutTreeActionType.Swap,
|
||||
node1Id: node.id,
|
||||
node2Id: nodeToMove.id,
|
||||
node1Id: nodeId,
|
||||
node2Id: nodeToMoveId,
|
||||
};
|
||||
return swapAction;
|
||||
} else {
|
||||
@ -208,6 +221,7 @@ export function computeMoveNode(layoutState: LayoutTreeState, computeInsertActio
|
||||
}
|
||||
|
||||
export function moveNode(layoutState: LayoutTreeState, action: LayoutTreeMoveNodeAction) {
|
||||
console.log("moveNode", layoutState, action);
|
||||
const rootNode = layoutState.rootNode;
|
||||
if (!action) {
|
||||
console.error("no move node action provided");
|
||||
|
@ -86,8 +86,8 @@ export interface LayoutTreeAction {
|
||||
*/
|
||||
export interface LayoutTreeComputeMoveNodeAction extends LayoutTreeAction {
|
||||
type: LayoutTreeActionType.ComputeMove;
|
||||
node: LayoutNode;
|
||||
nodeToMove: LayoutNode;
|
||||
nodeId: string;
|
||||
nodeToMoveId: string;
|
||||
direction: DropDirection;
|
||||
}
|
||||
|
||||
|
@ -18,8 +18,8 @@ test("layoutTreeStateReducer - compute move", () => {
|
||||
let node1 = newLayoutNode(undefined, undefined, undefined, { blockId: "node1" });
|
||||
let pendingAction = computeMoveNode(treeState, {
|
||||
type: LayoutTreeActionType.ComputeMove,
|
||||
node: treeState.rootNode,
|
||||
nodeToMove: node1,
|
||||
nodeId: treeState.rootNode.id,
|
||||
nodeToMoveId: node1.id,
|
||||
direction: DropDirection.Bottom,
|
||||
});
|
||||
const insertOperation = pendingAction as LayoutTreeMoveNodeAction;
|
||||
@ -37,8 +37,8 @@ test("layoutTreeStateReducer - compute move", () => {
|
||||
let node2 = newLayoutNode(undefined, undefined, undefined, { blockId: "node2" });
|
||||
pendingAction = computeMoveNode(treeState, {
|
||||
type: LayoutTreeActionType.ComputeMove,
|
||||
node: node1,
|
||||
nodeToMove: node2,
|
||||
nodeId: node1.id,
|
||||
nodeToMoveId: node2.id,
|
||||
direction: DropDirection.Bottom,
|
||||
});
|
||||
const insertOperation2 = pendingAction as LayoutTreeMoveNodeAction;
|
||||
@ -64,8 +64,8 @@ test("computeMove - noop action", () => {
|
||||
);
|
||||
let moveAction: LayoutTreeComputeMoveNodeAction = {
|
||||
type: LayoutTreeActionType.ComputeMove,
|
||||
node: treeState.rootNode,
|
||||
nodeToMove,
|
||||
nodeId: treeState.rootNode.id,
|
||||
nodeToMoveId: nodeToMove.id,
|
||||
direction: DropDirection.Left,
|
||||
};
|
||||
let pendingAction = computeMoveNode(treeState, moveAction);
|
||||
@ -74,8 +74,8 @@ test("computeMove - noop action", () => {
|
||||
|
||||
moveAction = {
|
||||
type: LayoutTreeActionType.ComputeMove,
|
||||
node: treeState.rootNode,
|
||||
nodeToMove,
|
||||
nodeId: treeState.rootNode.id,
|
||||
nodeToMoveId: nodeToMove.id,
|
||||
direction: DropDirection.Right,
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user