in packages/ketcher-react/src/script/editor/tool/template.ts [446:602]
mouseup(event?) {
const dragCtx = this.dragCtx;
if (!dragCtx) {
return true;
}
delete this.dragCtx;
const restruct = this.editor.render.ctab;
let ci = dragCtx.item;
/* after moving around bond */
if (
dragCtx.action &&
ci &&
ci.map === 'bonds' &&
!this.isModeFunctionalGroup
) {
dragCtx.action.perform(restruct); // revert drag action
const promise = fromTemplateOnBondAction(
restruct,
this.template,
ci.id,
this.editor.event,
dragCtx.sign1 * dragCtx.sign2 > 0,
true,
) as Promise<any>;
promise.then(([action, pasteItems]) => {
const mergeItems = getItemsToFuse(this.editor, pasteItems);
action = fromItemsFuse(restruct, mergeItems).mergeWith(action);
this.editor.update(action);
});
return true;
}
/* end */
let action, functionalGroupRemoveAction;
if (
ci?.map === 'functionalGroups' &&
FunctionalGroup.isContractedFunctionalGroup(
ci.id,
this.functionalGroups,
) &&
this.isModeFunctionalGroup &&
this.targetGroupsIds.length
) {
const restruct = this.editor.render.ctab;
const functionalGroupToReplace = this.struct.sgroups.get(ci.id)!;
if (
this.isSaltOrSolvent &&
functionalGroupToReplace.isGroupAttached(this.struct)
) {
addOnCanvasWithoutMerge({
restruct,
template: this.template,
dragCtx,
editor: this.editor,
event,
});
return true;
}
functionalGroupRemoveAction = new Action();
const { atomId: sGroupPositionAtomId } =
functionalGroupToReplace.getContractedPosition(restruct.molecule);
const atomsWithoutAttachmentAtom = SGroup.getAtoms(
this.struct,
functionalGroupToReplace,
).filter((id) => id !== sGroupPositionAtomId);
functionalGroupRemoveAction.mergeWith(
fromSgroupDeletion(restruct, ci.id),
);
functionalGroupRemoveAction.mergeWith(
fromFragmentDeletion(restruct, { atoms: atomsWithoutAttachmentAtom }),
);
ci = { map: 'atoms', id: sGroupPositionAtomId };
}
if (!dragCtx.action) {
if (!ci) {
addOnCanvasWithoutMerge({
restruct,
template: this.template,
dragCtx,
editor: this.editor,
event,
});
return true;
} else if (ci.map === 'atoms') {
const degree = restruct.atoms.get(ci.id)?.a.neighbors.length;
if (degree && degree >= 1 && this.isSaltOrSolvent) {
addOnCanvasWithoutMerge({
restruct,
template: this.template,
dragCtx,
editor: this.editor,
event,
});
return true;
}
const angle = getAngleFromEvent(event, ci, restruct);
[action] = fromTemplateOnAtom(
restruct,
this.template,
ci.id,
angle,
false,
);
if (functionalGroupRemoveAction) {
action = functionalGroupRemoveAction.mergeWith(action);
}
dragCtx.action = action;
} else if (ci.map === 'bonds' && !this.isModeFunctionalGroup) {
const promise = fromTemplateOnBondAction(
restruct,
this.template,
ci.id,
this.editor.event,
dragCtx.sign1 * dragCtx.sign2 > 0,
true,
) as Promise<any>;
promise.then(([action, pasteItems]) => {
if (!this.isModeFunctionalGroup) {
const mergeItems = getItemsToFuse(this.editor, pasteItems);
action = fromItemsFuse(restruct, mergeItems).mergeWith(action);
this.editor.update(action);
}
});
return true;
}
}
for (const id of restruct.molecule.bonds.keys()) {
new BondAttr(id, 'isPreview', false).perform(restruct);
}
for (const id of restruct.molecule.atoms.keys()) {
new AtomAttr(id, 'isPreview', false).perform(restruct);
}
const completeAction = dragCtx.action;
if (completeAction && !completeAction.isDummy()) {
this.editor.update(completeAction);
}
this.editor.hover(this.editor.findItem(event, null), null, event);
return true;
}