From 894c8e45fbc74ca318c4ffcf3f49fb42139b4445 Mon Sep 17 00:00:00 2001 From: mohamedsalem401 Date: Wed, 25 Sep 2024 13:16:28 +0300 Subject: [PATCH] Fix triggering update event without moving any component --- .../core/src/utils/sorter/ComponentSorter.ts | 119 +++++++++++++----- packages/core/src/utils/sorter/Sorter.ts | 6 +- 2 files changed, 94 insertions(+), 31 deletions(-) diff --git a/packages/core/src/utils/sorter/ComponentSorter.ts b/packages/core/src/utils/sorter/ComponentSorter.ts index 0d6d394b0..d82f0c84c 100644 --- a/packages/core/src/utils/sorter/ComponentSorter.ts +++ b/packages/core/src/utils/sorter/ComponentSorter.ts @@ -70,47 +70,110 @@ export default class ComponentSorter extends } }; - private onDrop = (targetNode: NodeType | undefined, sourceNodes: NodeType[], index: number | undefined) => { - if (!targetNode) return; - index = typeof index === 'number' ? index : -1; - const model = this.sourceNodes?.[0].model; - const data = { - target: model, - // @ts-ignore - parent: model && model.parent(), - // @ts-ignore - index: model && model.index(), - }; - if (sourceNodes.length === 0) { - this.eventHandlers.legacyOnEndMove?.(null, this, { ...data }); + /** + * Handles the drop action by moving the source nodes to the target node. + * Calls appropriate handlers based on whether the move was successful or not. + * + * @param targetNode - The node where the source nodes will be dropped. + * @param sourceNodes - The nodes being dropped. + * @param index - The index at which to drop the source nodes. + */ + private onDrop = (targetNode: NodeType | undefined, sourceNodes: NodeType[], index: number | undefined): void => { + const at = typeof index === 'number' ? index : -1; + if (targetNode && sourceNodes.length > 0) { + const addedNodes = this.handleNodeAddition(targetNode, sourceNodes, at); + if (addedNodes.length === 0) this.triggerNullOnEndMove(false) + } else { + this.triggerNullOnEndMove(true); } - for (let idx = 0; idx < sourceNodes.length; idx++) { - const sourceNode = sourceNodes[idx]; - if (!targetNode.canMove(sourceNode, index)) continue; - const addedNode = this.addSourceNodeToTarget(sourceNode, targetNode, index); - this.eventHandlers.legacyOnEndMove?.(addedNode!.model, this, data); - } - targetNode.restNodeState(); + targetNode?.restNodeState(); this.placeholder.hide(); }; - private addSourceNodeToTarget(sourceNode: NodeType, targetNode: NodeType, index: number) { + /** + * Handles the addition of multiple source nodes to the target node. + * If the move is valid, adds the nodes at the specified index. + * + * @param targetNode - The target node where source nodes will be added. + * @param sourceNodes - The nodes being added. + * @param index - The index at which to add the source nodes. + * @returns The list of successfully added nodes. + */ + private handleNodeAddition(targetNode: NodeType, sourceNodes: NodeType[], index: number): NodeType[] { + return sourceNodes.reduce((addedNodes, sourceNode) => { + if (this.canMoveNode(targetNode, sourceNode, index)) { + const addedNode = this.moveNode(targetNode, sourceNode, index); + if (addedNode) addedNodes.push(addedNode); + } + return addedNodes; + }, [] as NodeType[]); + } + + /** + * Determines if a source node can be moved to the target node at the given index. + * + * @param targetNode - The node where the source node will be moved. + * @param sourceNode - The node being moved. + * @param index - The index at which to move the source node. + * @returns Whether the node can be moved. + */ + private canMoveNode(targetNode: NodeType, sourceNode: NodeType, index: number): boolean { + if (!targetNode.canMove(sourceNode, index)) return false; + const parent = sourceNode.getParent(); - let initialSourceIndex = -1; - if (parent) { - initialSourceIndex = parent.indexOfChild(sourceNode); - parent.removeChildAt(initialSourceIndex, { temporary: true }); + const initialSourceIndex = parent ? parent.indexOfChild(sourceNode) : -1; + if (parent?.model.cid === targetNode.model.cid && initialSourceIndex < index) { + index--; // Adjust index if moving within the same collection and after the initial position } + const isSameCollection = parent?.model.cid === targetNode.model.cid; - if (isSameCollection && initialSourceIndex < index) { - index--; + const isSameIndex = initialSourceIndex === index; + const insertingTextableIntoText = this.targetIsText && sourceNode.isTextable(); + + return !(isSameCollection && isSameIndex && !insertingTextableIntoText); + } + + /** + * Moves a source node to the target node at the specified index, handling edge cases. + * + * @param targetNode - The node where the source node will be moved. + * @param sourceNode - The node being moved. + * @param index - The index at which to move the source node. + * @returns The node that was moved and added, or null if it couldn't be moved. + */ + private moveNode(targetNode: NodeType, sourceNode: NodeType, index: number): NodeType { + const parent = sourceNode.getParent(); + if (parent) { + const initialSourceIndex = parent.indexOfChild(sourceNode); + parent.removeChildAt(initialSourceIndex, { temporary: true }); + + if (parent.model.cid === targetNode.model.cid && initialSourceIndex < index) { + index--; // Adjust index if moving within the same collection and after the initial position + } } - const addedNode = targetNode.addChildAt(sourceNode, index, { action: 'move-component' }); + const addedNode = targetNode.addChildAt(sourceNode, index, { action: 'move-component' }) as NodeType; + this.triggerEndMoveEvent(addedNode); + return addedNode; } + /** + * Triggers the end move event for a node that was added to the target. + * + * @param addedNode - The node that was moved and added to the target. + */ + private triggerEndMoveEvent(addedNode: NodeType): void { + this.eventHandlers.legacyOnEndMove?.(addedNode.model, this, { + target: addedNode.model, + // @ts-ignore + parent: addedNode.model && addedNode.model.parent(), + // @ts-ignore + index: addedNode.model && addedNode.model.index(), + }); + } + /** * Finalize the move by removing any helpers and selecting the target model. * diff --git a/packages/core/src/utils/sorter/Sorter.ts b/packages/core/src/utils/sorter/Sorter.ts index 472c2f440..4d1ff8591 100644 --- a/packages/core/src/utils/sorter/Sorter.ts +++ b/packages/core/src/utils/sorter/Sorter.ts @@ -171,7 +171,7 @@ export default class Sorter> { * Called when the drag operation should be cancelled */ cancelDrag(): void { - this.triggerOnEndMoveAfterCancel(); + this.triggerNullOnEndMove(true); this.dropLocationDeterminer.cancelDrag(); this.finalizeMove(); } @@ -219,7 +219,7 @@ export default class Sorter> { } // For the old sorter - private triggerOnEndMoveAfterCancel() { + protected triggerNullOnEndMove(dragIsCancelled: boolean) { const model = this.sourceNodes?.[0].model; const data = { target: model, @@ -229,6 +229,6 @@ export default class Sorter> { index: model && model.index(), }; - this.eventHandlers.legacyOnEndMove?.(null, this, { ...data, cancelled: 1 }); + this.eventHandlers.legacyOnEndMove?.(null, this, { ...data, cancelled: dragIsCancelled }); } }