|
|
|
@ -70,47 +70,110 @@ export default class ComponentSorter<NodeType extends BaseComponentNode> 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. |
|
|
|
* |
|
|
|
|